﻿using Glorysoft.Auto.Xfw;
using Glorysoft.Auto.Xfw.Entities;
using Glorysoft.EAP.Contracts.MESClient;
using Glorysoft.EAP.Contracts.MESClient.Models;
using Glorysoft.EAP.Core;
using Glorysoft.EAP.Core.Entities;
using Glorysoft.EAP.Core.Entities.DB;
using Glorysoft.EAP.Core.Enums;
using Glorysoft.EAP.EAPwell.web.entity;
using Glorysoft.EAP.RC.EAPClient;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using Org.BouncyCastle.Ocsp;
using Serilog.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Glorysoft.EAP.Contracts.MESClient.Models.TrackInResponse;
using static Microsoft.Graph.GeneratedErrorConstants;
using static Org.BouncyCastle.Math.EC.ECCurve;

namespace Glorysoft.EAP.RC.MES
{
    public class MESService : AbstractService
    {
        private readonly Logger CimLogger;
        protected readonly IConfiguration Config;
        protected static Logger TrackoutLogger = XfwContext.LogManager.Create("TrackOutLogger");
        public const string SystemNameRMS = "MESService";
        public string RMSError = "MESService time out.";
        public const string SystemNameEAP = "EAP";
        EAPClientService ClientService = null;
        // private DBServer dbServer = null;
        private DbService dbServer = null;
        public MESService()
        {
            try
            {
                CimLogger = XfwContext.LogManager.EapLogger;
                ClientService = new EAPClientService();
                dbServer = new DbService();
                //if (dbServer == null)
                //{
                //    dbServer = ReflectionHelper.Service<IDbService>();
                //}
            }
            catch (Exception ex)
            {
                CimLogger.Error(ex, $"{Name}.MESService() Execute Error.");

            }

        }
        public string Name => GetType().Name;
        public string CurrentMethod => MethodBase.GetCurrentMethod().Name;

        #region 用户登录
        public void Login(XfwArgs xfwArgs)
        {
            try
            {
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage("", MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.Login() The EAP has been switched Automatic Operation");
                    return;
                }
                string userName = xfwArgs.Header[CItems.UserName].ToString();
                string passWord = xfwArgs.Header[CItems.PassWord].ToString();
                string facilityId = xfwArgs.Header[CItems.FacilityId].ToString();
                SMECMESClient mclient = new SMECMESClient();
                var result = mclient.Login(userName, passWord, facilityId);
                xfwArgs.Header[CItems.Response] = result.success;
                xfwArgs.Header[CItems.MessageOrigin] = MessageOrigin.MES.ToString();
                if (string.IsNullOrEmpty(result.success) || result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.ReturnCode] = "NG";
                    xfwArgs.Header[CItems.ReturnMessage] = result.msg;
                    xfwArgs.Header[CItems.MessageType] = MessageType.Error.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation("LoginMESFAIL", userName, result.msg);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                }
                else
                {
                    xfwArgs.Header[CItems.ReturnCode] = "OK";
                    xfwArgs.Header[CItems.MessageType] = MessageType.Info.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation("LoginMESOK", userName);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                }
                xfwArgs.Header[CItems.FacilityId] = facilityId;
                xfwArgs.Header[CItems.UserName] = userName;
                Dict.Current.lotInfo.userName = userName;
                Dict.Current.lotInfo.facilityId = facilityId;
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.Login() Execute Error.");
            }
        }
        #endregion

        #region 获取批次信息
        public void GetCarrierLotInfo_MES(XfwArgs xfwArgs)
        {
            try
            {
                string equipmentId = xfwArgs.Header[CItems.EqpID].ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(equipmentId, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.GetCarrierLotInfo_MES() The EAP has been switched Automatic Operation");
                    return;
                }
                string lotId = xfwArgs.Header[CItems.LotID].ToString();
                string userName = xfwArgs.Header[CItems.UserName].ToString();
                string facilityId = xfwArgs.Header[CItems.FacilityId].ToString();


                SMECMESClient mclient = new SMECMESClient();
                //判断是不是MonitorLot
                LotinfoResponse result = new LotinfoResponse();
                Stopwatch sw = new Stopwatch();
                sw.Start();
                var res = mclient.GetMonitorCarrierLotInfo(lotId, equipmentId);
                bool monitorFlag = false;
                if (res != null && res["code"].ToString() == "200")
                {
                    monitorFlag = true;
                    var jObject = JsonConvert.DeserializeObject<JObject>(res["data"]["mesResponse"].ToString());
                    var ht_lotBaseInfo = jObject["lotBaseInfo"]?.ToString();

                    var jobject_unitsInfo = JsonConvert.DeserializeObject<JObject>(ht_lotBaseInfo);
                    var ht_unitsInfo = jobject_unitsInfo["unitsInfo"]?.ToString();

                    var ht_mvOutParameterSet = jObject["mvOutParameterSet"]?.ToString();
                    var resultmsg = res["data"]["mesResponse"].ToString();
                    result = JsonConvert.DeserializeObject<LotinfoResponse>(resultmsg);
                    result.lotBaseInfo.UnitList = JsonConvert.DeserializeObject<List<Contracts.MESClient.Models.unitsInfo>>(ht_unitsInfo);
                    if (!string.IsNullOrEmpty(ht_mvOutParameterSet))
                    {

                        var jobject_parameters = JsonConvert.DeserializeObject<JObject>(ht_mvOutParameterSet);
                        var ht_parameters = jobject_parameters["parameters"]?.ToString();
                        Dict.Current.parameterSet.parameterSetRrn = result.mvOutParameterSetInfo.parameterSetRrn = jobject_parameters["parameterSetRrn"]?.ToString();
                        Dict.Current.parameterSet.parameterSetVersion = result.mvOutParameterSetInfo.parameterSetVersion = jobject_parameters["parameterSetVersion"]?.ToString();
                        Dict.Current.parameterSet.parameterSetSpecRrn = result.mvOutParameterSetInfo.parameterSetSpecRrn = jobject_parameters["parameterSetSpecRrn"]?.ToString();
                        Dict.Current.parameterSet.parameterSize = result.mvOutParameterSetInfo.parameterSize = jobject_parameters["parameterSize"]?.ToString();
                        if (!string.IsNullOrEmpty(ht_parameters))
                        {
                            result.mvOutParameterSetInfo.parameters = JsonConvert.DeserializeObject<List<parameters>>(ht_parameters);
                            Dict.Current.parameterSet.parametersinfo = JsonConvert.DeserializeObject<List<Glorysoft.EAP.Core.Entities.Odyssey.parameters>>(ht_parameters);
                        }


                    }
                    result.success = "TRUE";
                    TrackoutLogger.Information("AutoMonitor作业");
                    ClientService.ShowMessage("当前批次为AutoMonitor作业");
                }
                else
                {
                    result = mclient.GetCarrierLotInfo(lotId, equipmentId, userName, facilityId);
                }
                sw.Stop();
                CimLogger.Information($"{Name}.调用MES webserver接口结果为:{result.success},耗时为:{sw.ElapsedMilliseconds}");
                if (result.success.ToUpper() != "TRUE")
                {
                    xfwArgs.Header[CItems.ReturnCode] = "NG";
                    xfwArgs.Header[CItems.ReturnMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG(result.msg);
                    xfwArgs.Header[CItems.MessageType] = MessageType.Error.ToString();
                    CimLogger.Warning($"{Name}.GetCarrierLotInfo_MES() result.success:{result.msg}");
                    //测试
                    //EAPClientService clientService = new EAPClientService();
                    //var messages = TranslateMsg.GetTranslation("S2F41DownLoadRecipeLotInfoIsNull");
                    //clientService.ShowMessage(Dict.Current.TesterID, MessageType.Alarm, messages, MessageOrigin.OCR);
                    //clientService.ShowMessage(Dict.Current.TesterID, MessageType.Warning, messages, MessageOrigin.OCR);
                    return;
                }
                xfwArgs.Header[CItems.LotID] = result.lotBaseInfo.lotId;
                xfwArgs.Header[CItems.EqpID] = equipmentId;
                xfwArgs.Header[CItems.lotType] = result.lotBaseInfo.lotType;
                xfwArgs.Header[CItems.batchId] = result.lotBaseInfo.batchId;
                xfwArgs.Header[CItems.operationId] = result.lotBaseInfo.operationId;
                xfwArgs.Header[CItems.productId] = result.lotBaseInfo.productId;
                xfwArgs.Header[CItems.WaferQty] = result.lotBaseInfo.qty1;
                Dict.Current.Qty = Convert.ToInt32(result.lotBaseInfo.qty1);
                var productId = result.lotBaseInfo.productId;
                xfwArgs.Header[CItems.UnitList] = JsonConvert.SerializeObject(result.lotBaseInfo.UnitList);
                xfwArgs.Header[CItems.ppid] = result.lotBaseInfo.ppid;
                xfwArgs.Header[CItems.recipeLogicalRrn] = result.lotBaseInfo.recipeLogicalRrn;
                xfwArgs.Header[CItems.reticleGroupId] = result.lotBaseInfo.reticleGroupId;
                xfwArgs.Header[CItems.reticleGroupRrn] = result.lotBaseInfo.reticleGroupRrn;
                xfwArgs.Header[CItems.lotStatus] = result.lotBaseInfo.lotStatus;
                xfwArgs.Header[CItems.stageId] = result.lotBaseInfo.stageId;
                xfwArgs.Header[CItems.Priority] = result.lotBaseInfo.priority;
                xfwArgs.Header[CItems.CustomerLotId] = result.lotBaseInfo.customerLotId;
                xfwArgs.Header[CItems.rcflag] = result.rcflag;

                var recipes = result.lotBaseInfo.ppid;
                xfwArgs.Header[CItems.Response] = JsonConvert.SerializeObject(result.lotBaseInfo);
                if (result.mvOutParameterSetInfo.parameters != null && result.mvOutParameterSetInfo.parameters.Count > 0)
                {
                    xfwArgs.Header[CItems.SamplePrompts] = JsonConvert.SerializeObject(result.mvOutParameterSetInfo.parameters[0].samplePrompts);
                    xfwArgs.Header[CItems.SamplePromptSize] = JsonConvert.SerializeObject(result.mvOutParameterSetInfo.parameters[0].samplePromptSize);
                }
                // xfwArgs.Header[CItems.SamplePrompts] =   JsonConvert.SerializeObject(result.mvOutParameterSetInfo.parametersinfo.samplePrompts);
                xfwArgs.Header[CItems.ReturnMessage] = result.msg;
                #region Dict.Current.lotInfo赋值
                Dict.Current.lotInfo.eqptID = xfwArgs.Header[CItems.EqpID]?.ToString();
                Dict.Current.lotInfo.lotId = xfwArgs.Header[CItems.LotID]?.ToString();
                Dict.Current.lotInfo.facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                Dict.Current.lotInfo.userName = xfwArgs.Header[CItems.UserName]?.ToString();
                Dict.Current.lotInfo.parameterSet = JsonConvert.SerializeObject(result.mvOutParameterSetInfo);
                Dict.Current.lotInfo.monitorLotFlag = false;

                
                //上报LotHistory
                LotHistory lotHistory = new LotHistory();
                lotHistory.productType = "P";
                lotHistory.lotName = result.lotBaseInfo.lotId;
                lotHistory.eventName = "Track In";
                lotHistory.productName = result.lotBaseInfo.productId;
                lotHistory.operationId = result.lotBaseInfo.operationId;
                lotHistory.eventData = JsonConvert.SerializeObject(result);
                lotHistory.eventUser = Dict.Current.lotInfo.eqptID;
                
                //当前批次第一次请求Lot信息时，初始化待作业wafer信息,
                //如果已经请求过lot信息，则保留原wafer测试结果。在下发作业指令时初始化待作业wafer
                var lotInfo = Dict.Current.lotInfo;
                if (monitorFlag)
                {
                    lotHistory.productType = "M";
                    lotInfo.monitorLotFlag = monitorFlag;
                    lotInfo.monitorConfig = JsonConvert.DeserializeObject<JObject>(res["data"]["monitorConfig"].ToString());
                    ClientService.ShowMessage("当前批次为Auto Monitor批次");
                }

                Dict.Current.lotInfo.waferList = new List<Wafer>();
                result.lotBaseInfo.UnitList.ForEach(unit =>
                {
                    Wafer wafer = new Wafer();
                    wafer.waferId = unit.t7code;
                    wafer.postion = unit.position;
                    wafer.processFlag = "N";
                    wafer.passNo = "0";
                    wafer.processState = ProcessState.Waitting.ToString();
                    Dict.Current.lotInfo.waferList.Add(wafer);
                });
                if (Dict.Current.TrackOutLotQueue.ContainsKey(lotInfo.lotId))
                {
                    Dict.Current.TrackOutLotQueue[lotInfo.lotId] = lotInfo;
                }
                else { 
                Dict.Current.TrackOutLotQueue.Add(lotInfo.lotId, lotInfo);
                }

                try
                {

                    JObject serverConfig = mclient.SaveLotHistory(lotHistory);
                    //if (serverConfig != null && serverConfig["data"] != null && (bool)serverConfig["data"]["monitorFlag"])
                    //{
                    //    string msg = "此产品型号Run 首次上机需先Run Monitor Wafer";
                    //    xfwArgs.Header["SuccessFlag"] = "NG";
                    //    xfwArgs.Header[CItems.ReturnMessage] = msg;
                    //    xfwArgs.SetReturnCodeNG(msg);
                    //    CimLogger.Warning($"{Name}.GetCarrierLotInfo_MES() result.success:{msg}");
                    //    ClientService.ShowAlarm(msg);
                    //    return;
                    //}
                }
                catch (Exception e) {
                    CimLogger.Warning($"{Name}.GetCarrierLotInfo_MES() result.Exception:{e}");
                }
                #endregion
                if (string.IsNullOrEmpty(recipes))
                {
                    string msg = "Recipe is Null";
                    xfwArgs.Header[CItems.ReturnCode] = "NG";
                    xfwArgs.Header[CItems.ReturnMessage] = msg;
                    xfwArgs.SetReturnCodeNG(msg);
                    CimLogger.Warning($"{Name}.GetCarrierLotInfo_MES() result.success:{msg}");
                    return;
                }
                //   Post(var baseurl = Config.GetSection("MES").Get<string>().Split(";")[1];)
                //特殊机台获取recipe取值不同
                if (Dict.Current.EAPName == "EAPTelKeysight" || Dict.Current.EAPName == "EAPTelKeysight2")
                {
                    if (recipes.Contains("_"))
                    {
                        var rcpArr = recipes.Split('_');
                        xfwArgs.Header[CItems.TestProgram] = recipes;
                        xfwArgs.Header[CItems.ProberRecipe] = rcpArr[0];
                    }
                }
                //F2特殊分割
                else if (Dict.Current.EAPName == "EAPUF2KAccoTest")
                {
                    if (recipes.Contains('@'))
                    {
                        var rcpArr = recipes.Split('@');
                        xfwArgs.Header[CItems.TestProgram] = rcpArr[0];
                        xfwArgs.Header[CItems.ProberRecipe] = rcpArr[1];
                    }
                    else
                    {
                        xfwArgs.Header[CItems.TestProgram] = recipes;
                        xfwArgs.Header[CItems.ProberRecipe] = recipes;
                    }
                }
                else
                {
                    var rcpArr = recipes.Split('@');
                    xfwArgs.Header[CItems.TestProgram] = rcpArr[0];
                    xfwArgs.Header[CItems.ProberRecipe] = rcpArr[1];
                }

                JObject rmsReply =  mclient.recipeCheckRequest((string)xfwArgs.Header[CItems.EqpID], (string)"PIL_PROD", (string)xfwArgs.Header[CItems.TestProgram]);
                if (rmsReply == null) {
                    CimLogger.Warning($"{Name}.GetCarrierLotInfo_MES() resultNull.success:rmsNull");
                    //string msg = "RMS 链接失败";
                    //xfwArgs.Header["SuccessFlag"] = "NG";
                    //xfwArgs.Header[CItems.ReturnMessage] = msg;
                    //xfwArgs.SetReturnCodeNG(msg);
                    //CimLogger.Warning($"{Name}.GetCarrierLotInfo_MES() result.success:{msg}");
                    //ClientService.ShowAlarm(msg);
                }
                if (rmsReply != null && rmsReply["code"].ToString() != "OK")
                {
                    string msg = rmsReply["message"]?.ToString();
                    xfwArgs.Header["SuccessFlag"] = "NG";
                    xfwArgs.Header[CItems.ReturnMessage] = msg;
                    xfwArgs.SetReturnCodeNG(msg);
                    CimLogger.Warning($"{Name}.GetCarrierLotInfo_MES() result.success:{msg}");
                    ClientService.ShowAlarm(msg);
                    return;
                }
                else if (rmsReply != null)
                {
                    ClientService.ShowMessage(rmsReply["message"]?.ToString());
                }
                else {
                    ClientService.ShowMessage("RMS返回为空");
                }
                CimLogger.Debug($"{Name}.GetCarrierLotInfo_MES() Dict.Current.EAPName:{Dict.Current.EAPName}");
                if (Dict.Current.EAPName == "EAPTelRaytrex" /*|| Dict.Current.EAPName == "EAPUF2KAccoTest"*/)  //非FP3000机台 目前无需验证针卡
                {
                    //if (xfwArgs.Header[CItems.lotStatus]?.ToString()?.ToUpper() == "WAITING") //当状态位WAITING 时，向MES发送进站请求
                    //{
                    //    TrackIn(xfwArgs);
                    //  TrackInResult(xfwArgs);
                    //}
                    //else
                    //{
                    //    var messagess = TranslateMsg.GetTranslation("MESManualTrackIn");
                    //    if (messagess != null && messagess.Count != 0)
                    //    {
                    //        ClientService.ShowMessage(equipmentId, MessageType.Info, messagess, MessageOrigin.MES);
                    //    }
                    //}
                    xfwArgs.Header[CItems.ReturnCode] = "OK";
                    xfwArgs.Header[CItems.ReturnMessage] = result.msg;
                    xfwArgs.SetReturnCodeOK();
                    return;

                }
                xfwArgs.Header[CItems.ReturnCode] = "OK";
                xfwArgs.Header[CItems.ReturnMessage] = result.msg;
                xfwArgs.SetReturnCodeOK();
                return;
                // }

            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.GetCarrierLotInfo_MES() Execute Error.");
            }
        }

        #endregion
        public void GetCarrierLotInfo_CHK(XfwArgs xfwArgs)
        {
            try
            {
                //开启测试
                //测试
                if (CItems.IsTest == "true" || Dict.Current.lotInfo.monitorLotFlag)
                {
                    xfwArgs.Header[CItems.ReturnCode] = "OK";
                    xfwArgs.SetReturnCodeOK();
                    CimLogger.Information($"{Name}.GetCarrierLotInfo_CHK(), Dict.Current.EAPName:{Dict.Current.EAPName} , 非UF2000机台 目前无需验证针卡");
                    return;
                }
                var product = "";
                string equipmentId = xfwArgs.Header[CItems.EqpID].ToString();
                if (Dict.Current.EAPName.Contains("EAPTelKeysight") /*|| Dict.Current.EAPName.Contains("EAPUF2KAccoTest")*/)  //非FP3000/UF2000机台 目前无需验证针卡，流程终止
                {
                    xfwArgs.Header[CItems.ReturnCode] = "OK";
                    xfwArgs.SetReturnCodeOK();
                    CimLogger.Information($"{Name}.GetCarrierLotInfo_CHK(), Dict.Current.EAPName:{Dict.Current.EAPName} , 非UF2000机台 目前无需验证针卡");
                    return;
                }
                else if (xfwArgs.Header[CItems.ReturnCode]?.ToString() == "NG")
                {
                    CimLogger.Information($"{Name}.GetCarrierLotInfo_CHK(), 没有找到Lot信息，无需检查针卡");
                    return;
                }

                Stopwatch sw = new Stopwatch();
                MSAccessHelper mSAccessHelper = new MSAccessHelper();
                sw.Start();
                var jieguo = "";
                if (Dict.Current.EAPName == "EAPServer")
                {
                    jieguo = mSAccessHelper.MSAccessConnect(equipmentId, Dict.Current.lotInfo.ProberCardId, xfwArgs.Header[CItems.productId]?.ToString());
                }
                else
                {
                    if (Dict.Current.lotInfo.facilityId == "F2")
                    {
                        if (Dict.Current.EAPName.Contains("EAPUF2KAccoTest"))
                        {
                            product = xfwArgs.Header[CItems.ProberRecipe].ToString().Split("-")[0];//查找productid； 取proberrecipeid值第一个"-"的值
                        }
                        else
                        {
                            product = xfwArgs.Header[CItems.productId].ToString();
                        }
                    }
                    else
                    {
                        product = xfwArgs.Header[CItems.ProberRecipe].ToString().Split("-")[0];//查找productid； 取proberrecipeid值第一个"-"的值
                    }

                    jieguo = mSAccessHelper.MSAccessConnectQuery(equipmentId, Dict.Current.lotInfo.ProberCardId, product);
                }
                sw.Stop();
                CimLogger.Information($"{Name}.调用mSAccessHelper.MSAccessConnect结果为:{jieguo},耗时为:{sw.ElapsedMilliseconds}");
                if (jieguo == "success")
                {
                    xfwArgs.Header[CItems.ReturnCode] = "OK";
                    xfwArgs.SetReturnCodeOK();
                }
                else
                {
                    xfwArgs.Header[CItems.ReturnCode] = "NG";
                    xfwArgs.Header[CItems.ReturnMessage] = jieguo;
                    xfwArgs.SetReturnCodeNG(jieguo);
                    CimLogger.Warning($"{Name}.GetCarrierLotInfo_CHK()   jieguo:{jieguo}");
                }
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.GetCarrierLotInfo_CHK() Execute Error.");
            }
        }

        #region 验证批次信息，批次进站
        public void TrackIn(XfwArgs xfwArgs)
        {
            try
            {
                var eqpid = Dict.Current.lotInfo.eqptID;//xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackIn() The EAP has been switched Automatic Operation");
                    return;
                }

                #region TrackIn前 批次状态判断
                var lotStatus = xfwArgs.Header[CItems.lotStatus]?.ToString()?.ToUpper();
                CimLogger.Information($"{Name} TrackIn().lotId:{Dict.Current.lotInfo.lotId}, lotStatus:{lotStatus}");
                if (lotStatus == "RUNNING" || Dict.Current.lotInfo.monitorLotFlag)
                {
                    var messagess = TranslateMsg.GetTranslation("MESManualTrackIn", Dict.Current.lotInfo.lotId);
                    if (messagess != null && messagess.Count != 0)
                    {
                        ClientService.ShowMessage(Dict.Current.lotInfo.eqptID, MessageType.Info, messagess, MessageOrigin.MES);
                    }
                    return;
                }
                #endregion

                var lotID = Dict.Current.lotInfo.lotId; //xfwArgs.Header[CItems.LotID]?.ToString();
                var userName = Dict.Current.lotInfo.userName; //xfwArgs.Header[CItems.UserName]?.ToString();
                var facilityId = Dict.Current.lotInfo.facilityId; // xfwArgs.Header[CItems.FacilityId]?.ToString();
                SMECMESClient mesClient = new SMECMESClient();
                var listbaseInfo = new List<BaseInfo>();
                BaseInfo baseInfo = new BaseInfo();
                LotBaseInfo lotbaseInfo = new LotBaseInfo();
                lotbaseInfo.chamberType = "";
                lotbaseInfo.lotId = lotID;
                lotbaseInfo.ppid = Dict.Current.lotInfo.ppid; //xfwArgs.Header[CItems.ppid]?.ToString();
                lotbaseInfo.recipeLogicalRrn = Dict.Current.lotInfo.recipeLogicalRrn; // xfwArgs.Header[CItems.recipeLogicalRrn]?.ToString();
                lotbaseInfo.reticleGroupId = Dict.Current.lotInfo.reticleGroupId; // xfwArgs.Header[CItems.reticleGroupId]?.ToString();
                lotbaseInfo.reticleGroupRrn = Dict.Current.lotInfo.reticleGroupRrn; // xfwArgs.Header[CItems.reticleGroupRrn]?.ToString();
                lotbaseInfo.trackFlag = "in";
                baseInfo.lotBaseInfo = lotbaseInfo;
                listbaseInfo.Add(baseInfo);
                var jsonvalue = JsonConvert.SerializeObject(listbaseInfo);
                var trackin = mesClient.dispatchLotIn(facilityId, userName, eqpid, lotID, jsonvalue);
                if (trackin == null)
                {
                    //发送Client TrackIn失败
                    xfwArgs.Header[CItems.TrackInReturnCode] = "1";
                    xfwArgs.Header[CItems.TrackInMessage] = "Interface response timeout";
                    xfwArgs.SetReturnCodeNG("TrackIn: trackin==null,Interface response timeout");
                    //msgs = TranslateMsg.GetTranslation(CItems.MESTrackInNG, "Interface response timeout");
                    //msgType = MessageType.Error;
                    xfwArgs.Header[CItems.ReturnCode] = "NG";
                    xfwArgs.Header[CItems.ReturnMessage] = xfwArgs.Header[CItems.TrackInMessage];
                    return;

                }
                else if (trackin.success.ToUpper() == "FALSE")
                {
                    //发送Client TrackIn失败
                    xfwArgs.Header[CItems.TrackInReturnCode] = "1";
                    xfwArgs.Header[CItems.TrackInMessage] = trackin.msg;
                    xfwArgs.SetReturnCodeNG(trackin.msg);
                    //msgs = TranslateMsg.GetTranslation(CItems.MESTrackInNG, trackin.msg);
                    //msgType = MessageType.Error;
                    xfwArgs.Header[CItems.ReturnCode] = "NG";
                    xfwArgs.Header[CItems.ReturnMessage] = trackin.msg;
                    return;
                }

                Dictionary<string, string> msgs = TranslateMsg.GetTranslation(CItems.MESTrackInOK);  //MESTrackInOK
                var msgType = MessageType.Info;
                xfwArgs.Header[CItems.TrackInReturnCode] = "0";
                xfwArgs.Header[CItems.lotStatus] = "RUNNING";  //进站后将批次状态改为 RUNNING
                Dict.Current.lotInfo.lotStatus = "RUNNING";

                xfwArgs.SetReturnCodeOK();
                if (msgs != null && msgs.Count != 0)
                {
                    ClientService.ShowMessage(Dict.Current.lotInfo.eqptID, msgType, msgs, MessageOrigin.MES);
                }


            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.SaveTest() Execute Error.");
            }
        }
        #endregion
        public void TrackOutWAT(XfwArgs xfwArgs)
        {
            try
            {
                var eqpid = Dict.Current.lotInfo.eqptID;
                if (string.IsNullOrEmpty(eqpid))
                    eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOut() The EAP has been switched Automatic Operation");
                    return;
                }
                var lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                if (string.IsNullOrEmpty(lotID))
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = "TrackOut: lotid==null";
                    xfwArgs.SetReturnCodeNG("TrackOut: lotid==null");
                    return;
                }
                var userName = xfwArgs.Header[CItems.UserName]?.ToString();
                if (string.IsNullOrEmpty(userName))
                    userName = Dict.Current.lotInfo.userName;
                var facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = Dict.Current.lotInfo.facilityId;
                xfwArgs.Header[CItems.EqpID] = eqpid;
                CimLogger.Information($"TrackOut:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                mvOutParameterSet parameterInfo = new mvOutParameterSet();
                var lotParamStr = "";
                if (CItems.lotParamDic.ContainsKey(lotID))
                    lotParamStr = CItems.lotParamDic[lotID];
                if (!string.IsNullOrEmpty(lotParamStr))
                    parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotParamStr);
                CimLogger.Information($"TrackOut:parameterInfo:{JsonConvert.SerializeObject(parameterInfo)}");
                CimLogger.Information($"TrackOut:waferInfoDic:{JsonConvert.SerializeObject(CItems.waferInfoDic)}");
                xfwArgs.Header[CItems.EqpID] = eqpid;
                SMECMESClient mesClient = new SMECMESClient();
                var listbaseInfo = new List<BaseInfo>();
                var parameterSet = new List<mvOutParameterSet>();
                BaseInfo baseInfo = new BaseInfo();
                LotBaseInfo lotbaseInfo = new LotBaseInfo();
                lotbaseInfo.lotId = lotID;
                lotbaseInfo.trackFlag = "out";
                baseInfo.lotBaseInfo = lotbaseInfo;
                var aa = CItems.waferInfoDic;
               
                listbaseInfo.Add(baseInfo);
                var jsonvalue2 = JsonConvert.SerializeObject(listbaseInfo);
                string jsonvalue = jsonvalue2;
                CimLogger.Information(jsonvalue2);
                if (!string.IsNullOrEmpty(jsonvalue2))
                {
                    var hz = jsonvalue2.Substring(jsonvalue2.Length - 3);
                    CimLogger.Information("hz=" + hz);
                    if (hz != "}}]")
                    {
                        jsonvalue = jsonvalue2.Substring(0, jsonvalue2.Length - 2) + "}}]";
                        CimLogger.Information("jsonvalue=" + jsonvalue);
                    }
                }
                CimLogger.Information("jsonvalue2=" + jsonvalue);
             
                //出站增加延迟，等待MES收值
                if (CItems.TrackOutSleep > 0)
                {
                    if (CItems.IsTest != "true")
                    {
                        Thread.Sleep(1000 * 60 * CItems.TrackOutSleep);
                    }
                     
                }
                var result = mesClient.dispatchLotOut(facilityId, userName, eqpid, lotID, jsonvalue);
                //出站后清空字典
                CItems.lotParamDic.Remove(lotID);
                CItems.waferInfoDic = new Dictionary<string, string>();
                if (result == null)
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = "TrackOut: TrackOut==null";
                    xfwArgs.SetReturnCodeNG("TrackOut: TrackOut==null");
                    return;
                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG("TrackOut: result.success==False");
                    return;
                }
              
                xfwArgs.Header[CItems.TrackOutReturnCode] = "0";
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.SaveTest() Execute Error.");
            }
        }


        #region 出站发送End Test
        public void TrackOut(XfwArgs xfwArgs)
        {
            try
            {
                //var eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                var eqpid = Dict.Current.lotInfo.eqptID;
                if (string.IsNullOrEmpty(eqpid))
                    eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOut() The EAP has been switched Automatic Operation");
                    return;
                }
                var lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                if (string.IsNullOrEmpty(lotID))
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = "TrackOut: lotid==null";
                    xfwArgs.SetReturnCodeNG("TrackOut: lotid==null");
                    return;
                }
                var userName = xfwArgs.Header[CItems.UserName]?.ToString();
                if (string.IsNullOrEmpty(userName))
                    userName = Dict.Current.lotInfo.userName;
                var facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = Dict.Current.lotInfo.facilityId;
                xfwArgs.Header[CItems.EqpID] = eqpid;
                CimLogger.Information($"TrackOut:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                mvOutParameterSet parameterInfo = new mvOutParameterSet();
                var lotParamStr = "";
                if (CItems.lotParamDic.ContainsKey(lotID))
                    lotParamStr = CItems.lotParamDic[lotID];
                if (!string.IsNullOrEmpty(lotParamStr))
                    parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotParamStr);
                CimLogger.Information($"TrackOut:parameterInfo:{JsonConvert.SerializeObject(parameterInfo)}");
                CimLogger.Information($"TrackOut:waferInfoDic:{JsonConvert.SerializeObject(CItems.waferInfoDic)}");
                xfwArgs.Header[CItems.EqpID] = eqpid;
                SMECMESClient mesClient = new SMECMESClient();
                var listbaseInfo = new List<BaseInfo>();
                var parameterSet = new List<mvOutParameterSet>();
                BaseInfo baseInfo = new BaseInfo();
                LotBaseInfo lotbaseInfo = new LotBaseInfo();
                lotbaseInfo.lotId = lotID;
                lotbaseInfo.trackFlag = "out";
                baseInfo.lotBaseInfo = lotbaseInfo;
                var aa = CItems.waferInfoDic;
                foreach (var item in parameterInfo.parameters)
                {
                    var parameterId = item.parameterId.Split('-');
                    var parame = parameterId[parameterId.Length - 1].ToString();
                    foreach (var item1 in item.samplePrompts)
                    {
                        var name = item1.unitId.Replace("#", "-").ToString() + "_" + parame;
                        var paravale = CItems.waferInfoDic.ContainsKey(name);
                        if (!paravale)
                        {
                            name = "0" + item1.unitId.Split('#')[1].ToString() + "_" + parame;
                            paravale = CItems.waferInfoDic.ContainsKey(name);
                        }
                        foreach (var item2 in item1.readingPrompts)
                        {
                            if (paravale)
                            {
                                string val = CItems.waferInfoDic[name].ToString().Replace("%", "");
                                if (string.IsNullOrEmpty(val))
                                    item2.dataValue = "0";
                                else
                                {
                                    double dataValue = double.Parse(val);
                                    if (dataValue > 0 || dataValue < 0)
                                        item2.dataValue = Math.Round((dataValue / 100.00), 4).ToString();
                                    else
                                        item2.dataValue = "0";
                                }
                            }
                            else
                            {
                                //未在文件中找到值
                                xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                                xfwArgs.Header[CItems.TerminalMessage] = $"TrackOut: param:{name}==null";
                                xfwArgs.SetReturnCodeNG($"TrackOut: param:{name}==null");
                                return;
                            }
                        }
                    }
                }
                baseInfo.parameterSet = parameterInfo;
                listbaseInfo.Add(baseInfo);
                var jsonvalue2 = JsonConvert.SerializeObject(listbaseInfo);
                string jsonvalue = jsonvalue2;
                CimLogger.Information(jsonvalue2);
                if (!string.IsNullOrEmpty(jsonvalue2))
                {
                    var hz = jsonvalue2.Substring(jsonvalue2.Length - 3);
                    CimLogger.Information("hz=" + hz);
                    if (hz != "}}]")
                    {
                        jsonvalue = jsonvalue2.Substring(0, jsonvalue2.Length - 2) + "}}]";
                        CimLogger.Information("jsonvalue=" + jsonvalue);
                    }
                }
                CimLogger.Information("jsonvalue2=" + jsonvalue);
                var result = mesClient.dispatchLotOut(facilityId, userName, eqpid, lotID, jsonvalue);
                //出站后清空字典
                CItems.lotParamDic.Remove(lotID);
                CItems.waferInfoDic = new Dictionary<string, string>();
                if (result == null)
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = "TrackOut: TrackOut==null";
                    xfwArgs.SetReturnCodeNG("TrackOut: TrackOut==null");
                    return;
                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG("TrackOut: result.success==False");
                    return;
                }
                //Trackout成功后保存数据文件到backUp文件夹中
                try
                {
                    //foreach (var item in parameterInfo.parameters)
                    //{
                    //    foreach (var item1 in item.samplePrompts)
                    //    {
                    //        var fileh = item1.unitId.Replace("#", "-");
                    //        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP"))
                    //            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP");
                    //        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP\\CP1"))
                    //            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP\\CP1");
                    //        var filePath = CItems.FtpAddress + "\\CP1\\" + fileh + ".txt";//暂时使用CP1}
                    //        var backfilePath = CItems.FtpAddress + "\\BACKUP\\CP1\\" + fileh + ".txt";//暂时使用CP1
                    //        if (File.Exists(backfilePath))
                    //            File.Delete(backfilePath);
                    //        File.Copy(filePath, backfilePath);
                    //        File.Delete(filePath);
                    //    }
                    //}

                    var slidesList = xfwArgs.Header[CItems.slidesInfo]?.ToString() == null ? new string[1] : xfwArgs.Header[CItems.slidesInfo]?.ToString().Split(';');
                    #region  F1
                    for (int i = 0; i < slidesList.Length; i++)
                    {
                        if (string.IsNullOrEmpty(slidesList[i]?.ToString()))
                            continue;
                        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP"))
                            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP");
                        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP\\CP1"))
                            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP\\CP1");
                        var _lotid = lotID.Split('-')[0].ToString();
                        if (_lotid.Contains('.'))
                            _lotid = _lotid.Split('.')[0].ToString();
                        var filePath = CItems.FtpAddress + "\\CP\\CP1\\" + _lotid + "-" + slidesList[i] + ".txt";//暂时使用CP1}
                        var backfilePath = CItems.FtpAddress + "\\BACKUP\\CP1\\" + _lotid + "-" + slidesList[i] + ".txt";//暂时使用CP1
                        if (File.Exists(backfilePath))
                            File.Delete(backfilePath);
                        File.Copy(filePath, backfilePath);
                        File.Delete(filePath);
                    }
                    #endregion
                    #region  F2
                    //for (int i = 0; i < slidesList.Length; i++)
                    //{
                    //    if (string.IsNullOrEmpty(slidesList[i]?.ToString()))
                    //        continue;
                    //    if (!Directory.Exists("\\\\10.190.221.100\\eda_f2_sx\\mes\\BACKUP"))
                    //        Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP");
                    //    var _lotid = lotID.Split('-')[0].ToString();
                    //    if (_lotid.Contains('.'))
                    //        _lotid = _lotid.Split('.')[0].ToString();
                    //    var filePath = CItems.FtpAddress + "\\CP\\" + _lotid + "-" + slidesList[i] + ".txt";
                    //    var backfilePath = "\\\\10.190.221.100\\eda_f2_sx\\mes\\BACKUP" + _lotid + "-" + slidesList[i] + ".txt";
                    //    if (File.Exists(backfilePath))
                    //        File.Delete(backfilePath);
                    //    File.Copy(filePath, backfilePath);
                    //    File.Delete(filePath);
                    //}
                    #endregion

                }
                catch (Exception ex)
                {
                    HoldRuningLot(xfwArgs);
                    CimLogger.Information($"TrackOut-FileBackUp:{ex.ToString()}");
                }

                //Dict.Current.lotInfo = new LotInfo();
                xfwArgs.Header[CItems.TrackOutReturnCode] = "0";
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.SaveTest() Execute Error.");
            }
        }

        public bool IsSpecialFailMsg(string msg)
        {
            var specialMsg = string.IsNullOrEmpty(CItems.TrackOutFailInfo) ? "RUNNINGHOLD;status is invalid;EDM" : CItems.TrackOutFailInfo;
            var msgs = specialMsg.Split(';');
            foreach (var row in msgs)
            {
                if (msg.Contains(row))
                {
                    return true;
                }
            }
            return false;
        }

        public bool backupMapFile(LotInfo lotInfo)
        {
            //Trackout成功后保存数据文件到backUp文件夹中
            try
            {
                foreach (Wafer wafer in lotInfo.waferList)
                {
                    var waferId = wafer.waferId.Split("-")[0] + "-" + wafer.waferId.Split("-")[1];
                    //if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP"))
                    //    Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP");
                    //if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP\\CP1"))
                    //    Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP\\CP1");
                    var filePath = CItems.FtpAddress + "\\CP\\CP1\\" + waferId + ".txt";//暂时使用CP1}
                    var backfilePath = CItems.FtpAddress + "\\BACKUP\\CP1\\" + waferId + ".txt";//暂时使用CP1
                    TrackoutLogger.Information($"备份MAP文件，filePath：{filePath} backupPath: {backfilePath}");
                    if (File.Exists(backfilePath))
                        File.Delete(backfilePath);
                    File.Copy(filePath, backfilePath);
                    File.Delete(filePath);
                    TrackoutLogger.Information($"备份MAP文件成功");
                }
            }
            catch (Exception e)
            {
                TrackoutLogger.Information($"备份MAP文件异常，报错为：{e.Message}");
                return false;
            }
            return true;
        }

        public bool sendTrackOut(LotInfo lotInfo)
        {
            //var eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
            var eqpid = lotInfo.eqptID;
            var lotID = lotInfo.lotId;
            var userName = lotInfo.userName;
            var facilityId = lotInfo.facilityId;

            TrackoutLogger.Information($"开始发送出站请求:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
            mvOutParameterSet parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotInfo.parameterSet);
            SMECMESClient mesClient = new SMECMESClient();
            var listbaseInfo = new List<BaseInfo>();
            var parameterSet = new List<mvOutParameterSet>();
            BaseInfo baseInfo = new BaseInfo();
            LotBaseInfo lotbaseInfo = new LotBaseInfo();
            lotbaseInfo.lotId = lotID;
            lotbaseInfo.trackFlag = "out";
            baseInfo.lotBaseInfo = lotbaseInfo;
            var aa = CItems.waferInfoDic;
            baseInfo.parameterSet = parameterInfo;
            listbaseInfo.Add(baseInfo);
            var jsonvalue2 = JsonConvert.SerializeObject(listbaseInfo);
            string jsonvalue = jsonvalue2;
            if (!string.IsNullOrEmpty(jsonvalue2))
            {
                var hz = jsonvalue2.Substring(jsonvalue2.Length - 3);
                if (hz != "}}]")
                {
                    jsonvalue = jsonvalue2.Substring(0, jsonvalue2.Length - 2) + "}}]";
                }
            }
            var result = mesClient.dispatchLotOut(facilityId, userName, eqpid, lotID, jsonvalue);

            if (result == null)
            {
                TrackoutLogger.Information($"MES回复为空，{lotInfo.lotId}出站失败,加入到待出站队列中");
                lotInfo.trackOutRetryCount++;
                return false;
            }
            else if (result.success.ToUpper() == "FALSE")
            {
                var messages = TranslateMsg.GetTranslation("TrackOutFail", CItems.TrackOutPl, CItems.TrackOutTotal, lotInfo.lotId + ":" + result.msg);
                ClientService.ShowMessage(Dict.Current.TesterID, MessageType.Error, messages, MessageOrigin.OCR);
                if (IsSpecialFailMsg(result.msg))
                {
                    lotInfo.trackOutRetryCount++;
                    TrackoutLogger.Information($"MES回复出站失败，回复消息包含特殊字符，增加批次出站次数：{lotInfo.lotId}");
                }
                else
                {
                    TrackoutLogger.Information($"MES回复出站失败，返回值不是特殊字符，移除自动出站：{lotInfo.lotId}");
                    lotInfo.trackOutRetryCount = CItems.TrackOutCount + 1;

                }
                return false;
            }
            TrackoutLogger.Information($"MES回复出站成功,移除出账队列！！！！！！：{lotInfo.lotId}");
            lotInfo.trackOutRetryCount = CItems.TrackOutCount + 1;
            return true;
        }
        public void HoldLotByLotInfo(LotInfo lotInfo, string reasons)
        {
            try
            {
                var eqpid = lotInfo.eqptID;
                var lotID = lotInfo.lotId;
                if (string.IsNullOrEmpty(lotID) || string.IsNullOrEmpty(eqpid))
                {
                    TrackoutLogger.Error("lotID或设备ID为空，hold Lot失败");
                    return;
                }
                var userName = lotInfo.userName;
                if (string.IsNullOrEmpty(userName))
                    userName = Dict.Current.lotInfo.userName;
                var facilityId = lotInfo.facilityId;
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = Dict.Current.lotInfo.facilityId;
                CimLogger.Information($"HoldRuningLot:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                var group = "YE";
                var groupCode = "YE_TE_OTHER";
                SMECMESClient mesClient = new SMECMESClient();
                var result = mesClient.holdRuningLot(facilityId, userName, eqpid, lotID, group, groupCode, reasons);

            }
            catch (Exception ex)
            {
                TrackoutLogger.Error($"hold Lot失败{ex.Message}");
            }
        }


        public void TrackOutLot(XfwArgs xfwArgs)
        {
            try
            {
                LotInfo lotInfo = (LotInfo)xfwArgs.Header[CItems.LotInfo];
                TrackOutLotRetry(lotInfo);
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.TrackOutLot() Execute Error.");
            }
        }

        public void TrackOutLotRetry(LotInfo lotInfo)
        {
            try
            {
                if (lotInfo.yieldFlag)
                {
                    TrackoutLogger.Information($"{lotInfo.lotId} 良率已收，重试出账");
                    sendTrackOut(lotInfo);
                }
                else
                {
                    if (!CheckMapFileExist(lotInfo))
                    {
                        lotInfo.trackOutRetryCount++;
                        TrackoutLogger.Information($"{lotInfo.lotId} 校验Map文件是否存在失败，等待下一次执行，当前已失败{lotInfo.trackOutRetryCount}次");
                        return;
                    }
                    if (!checkPassDieAndSavePara(lotInfo))
                    {
                        TrackoutLogger.Information($"{lotInfo.lotId} 比对PassNo失败，退出出站流程,将");
                        lotInfo.trackOutRetryCount = CItems.TrackOutCount + 1;
                        return;
                    }
                    lotInfo.yieldFlag = false;
                    lotInfo.yieldFlag = updateWaferYield(lotInfo);
                    if (!lotInfo.yieldFlag)
                    {
                        TrackoutLogger.Information($"{lotInfo.lotId} 良率收值失败,出站次数增加");
                        lotInfo.trackOutRetryCount++;
                        return;
                    }
                    backupMapFile(lotInfo);
                    sendTrackOut(lotInfo);
                }
            }
            catch (Exception ex)
            {
                CimLogger.Error(ex, $"{Name}.TrackOutLotRetry() Execute Error.");
                lotInfo.trackOutRetryCount = CItems.TrackOutCount + 1;
            }
        }


        public void TrackOutLotLuDing(LotInfo lotInfo)
        {
            try
            {
                //泸定出账先判断是不是要收值P50
                if (IsSampleProduct(lotInfo))
                {
                    TrackoutLogger.Information($"批次{lotInfo.lotId}开始收值P50");
                    if (!CheckMapFileExist(lotInfo))
                    {
                        TrackoutLogger.Information($"{lotInfo.lotId} 校验Map文件是否存在失败，等待下一次执行");
                        return;
                    }
                    if (!checkP50AndSavePara(lotInfo))
                    {
                        TrackoutLogger.Information($"{lotInfo.lotId}P50比对失败，等待下一次执行");
                        return;
                    }
                    if (!updateWaferValue(lotInfo))
                    {
                        TrackoutLogger.Information($"{lotInfo.lotId} `P50收值失败，等待下一次执行");
                        return;
                    }

                    if (sendTrackOut(lotInfo))
                    {
                        backupMapFile(lotInfo);
                    }

                    lotInfo.trackOutRetryCount = CItems.TrackOutCount + 1;

                }
                //非P50出账，收值Xls9个点位
                else
                {
                    TrackoutLogger.Information($"批次{lotInfo.lotId}开始收值九点");
                    if (!CheckXlsxFileExist(lotInfo))
                    {
                        TrackoutLogger.Information($"{lotInfo.lotId} 校验Xlsx文件是否存在失败，等待下一次执行");
                        return;
                    }
                    if (!updateWaferValueList(lotInfo))
                    {
                        TrackoutLogger.Information($"{lotInfo.lotId}收值失败,等待下次收值");
                        return;
                    }
                    sendTrackOut(lotInfo);
                    //泸定只出一次
                    lotInfo.trackOutRetryCount = CItems.TrackOutCount + 1;
                }

            }
            catch (Exception ex)
            {
                TrackoutLogger.Information(ex, $"{Name}.TrackOutLotRetry() Execute Error.");
                lotInfo.trackOutRetryCount = CItems.TrackOutCount + 1;
            }
        }
        public void TrackOut_Delay(XfwArgs xfwArgs)
        {
            try
            {
                //var eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                var eqpid = Dict.Current.lotInfo.eqptID;
                if (string.IsNullOrEmpty(eqpid))
                    eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOut() The EAP has been switched Automatic Operation");
                    return;
                }
                var lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                if (string.IsNullOrEmpty(lotID))
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = "TrackOut: lotid==null";
                    xfwArgs.SetReturnCodeNG("TrackOut: lotid==null");
                    return;
                }
                var userName = xfwArgs.Header[CItems.UserName]?.ToString();
                if (string.IsNullOrEmpty(userName))
                    userName = Dict.Current.lotInfo.userName;
                var facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = Dict.Current.lotInfo.facilityId;
                xfwArgs.Header[CItems.EqpID] = eqpid;
                CimLogger.Information($"TrackOut:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                mvOutParameterSet parameterInfo = new mvOutParameterSet();
                var lotParamStr = "";
                if (CItems.lotParamDic.ContainsKey(lotID))
                    lotParamStr = CItems.lotParamDic[lotID];
                if (!string.IsNullOrEmpty(lotParamStr))
                    parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotParamStr);
                CimLogger.Information($"TrackOut:parameterInfo:{JsonConvert.SerializeObject(parameterInfo)}");
                CimLogger.Information($"TrackOut:waferInfoDic:{JsonConvert.SerializeObject(CItems.waferInfoDic)}");
                xfwArgs.Header[CItems.EqpID] = eqpid;
                SMECMESClient mesClient = new SMECMESClient();
                var listbaseInfo = new List<BaseInfo>();
                var parameterSet = new List<mvOutParameterSet>();
                BaseInfo baseInfo = new BaseInfo();
                LotBaseInfo lotbaseInfo = new LotBaseInfo();
                lotbaseInfo.lotId = lotID;
                lotbaseInfo.trackFlag = "out";
                baseInfo.lotBaseInfo = lotbaseInfo;
                var aa = CItems.waferInfoDic;
                if (CItems.IsTest != "true")
                {
                    foreach (var item in parameterInfo.parameters)
                    {
                        var parameterId = item.parameterId.Split('-');
                        var parame = parameterId[parameterId.Length - 1].ToString();
                        foreach (var item1 in item.samplePrompts)
                        {
                            var name = item1.unitId.Split('#')[1].ToString() + "_" + parame;
                            var paravale = CItems.waferInfoDic.ContainsKey(name);
                            if (!paravale)
                            {
                                name = "0" + item1.unitId.Split('#')[1].ToString() + "_" + parame;
                                paravale = CItems.waferInfoDic.ContainsKey(name);
                            }
                            foreach (var item2 in item1.readingPrompts)
                            {
                                if (paravale)
                                {
                                    string val = CItems.waferInfoDic[name].ToString().Replace("%", "");
                                    if (string.IsNullOrEmpty(val))
                                        item2.dataValue = "0";
                                    else
                                    {
                                        double dataValue = double.Parse(val);
                                        if (dataValue > 0 || dataValue < 0)
                                            item2.dataValue = Math.Round((dataValue / 100.00), 4).ToString();
                                        else
                                            item2.dataValue = "0";
                                    }
                                }
                                else
                                {
                                    //未在文件中找到值
                                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                                    xfwArgs.Header[CItems.TerminalMessage] = $"TrackOut: param:{name}==null";
                                    xfwArgs.SetReturnCodeNG($"TrackOut: param:{name}==null");
                                    return;
                                }
                            }
                        }
                    }
                }
                baseInfo.parameterSet = parameterInfo;
                listbaseInfo.Add(baseInfo);
                var jsonvalue2 = JsonConvert.SerializeObject(listbaseInfo);
                string jsonvalue = jsonvalue2;
                CimLogger.Information(jsonvalue2);
                if (!string.IsNullOrEmpty(jsonvalue2))
                {
                    var hz = jsonvalue2.Substring(jsonvalue2.Length - 3);
                    CimLogger.Information("hz=" + hz);
                    if (hz != "}}]")
                    {
                        jsonvalue = jsonvalue2.Substring(0, jsonvalue2.Length - 2) + "}}]";
                        CimLogger.Information("jsonvalue=" + jsonvalue);
                    }
                }
                CimLogger.Information("jsonvalue2=" + jsonvalue);
                var result = mesClient.dispatchLotOut(facilityId, userName, eqpid, lotID, jsonvalue);
                if (!string.IsNullOrEmpty(CItems.TrackOutFailInfo))
                {
                    var msgs = CItems.TrackOutFailInfo.Split(';');
                    bool isFalg = false;
                    foreach (var row in msgs)
                    {
                        if (result.msg.Contains(row))
                        {
                            isFalg = true;
                            break;
                        }
                    }
                    if (isFalg)
                    {

                        //将lot存放在缓存中，后续可以存储在DB或文件中，以防止EAP重启缓存丢失
                        if (!CItems.TrackOutList.Keys.Contains(lotID))
                        {
                            CItems.TrackOutList.TryAdd(lotID, JsonConvert.SerializeObject(new
                            {
                                facilityId = facilityId,
                                userName = userName,
                                eqpid = eqpid,
                                lotID = lotID,
                                jsonvalue = jsonvalue,
                                Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                            }));
                        }
                    }
                }
                if (result == null)
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = "TrackOut: TrackOut==null";
                    xfwArgs.SetReturnCodeNG("TrackOut: TrackOut==null");
                    return;
                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG("TrackOut: result.success==False");
                    return;
                }

                //出站后清空字典
                CItems.lotParamDic.Remove(lotID);
                CItems.waferInfoDic = new Dictionary<string, string>();
                //Trackout成功后保存数据文件到backUp文件夹中
                try
                {
                    //foreach (var item in parameterInfo.parameters)
                    //{
                    //    foreach (var item1 in item.samplePrompts)
                    //    {
                    //        var fileh = item1.unitId.Replace("#", "-");
                    //        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP"))
                    //            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP");
                    //        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP\\CP1"))
                    //            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP\\CP1");
                    //        var filePath = CItems.FtpAddress + "\\CP1\\" + fileh + ".txt";//暂时使用CP1}
                    //        var backfilePath = CItems.FtpAddress + "\\BACKUP\\CP1\\" + fileh + ".txt";//暂时使用CP1
                    //        if (File.Exists(backfilePath))
                    //            File.Delete(backfilePath);
                    //        File.Copy(filePath, backfilePath);
                    //        File.Delete(filePath);
                    //    }
                    //}

                    var slidesList = xfwArgs.Header[CItems.slidesInfo]?.ToString() == null ? new string[1] : xfwArgs.Header[CItems.slidesInfo]?.ToString().Split(';');
                    #region  F1
                    for (int i = 0; i < slidesList.Length; i++)
                    {
                        if (string.IsNullOrEmpty(slidesList[i]?.ToString()))
                            continue;
                        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP"))
                            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP");
                        if (!Directory.Exists(CItems.FtpAddress + "\\BACKUP\\CP1"))
                            Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP\\CP1");
                        var _lotid = lotID.Split('-')[0].ToString();
                        if (_lotid.Contains('.'))
                            _lotid = _lotid.Split('.')[0].ToString();
                        var filePath = CItems.FtpAddress + "\\CP\\CP1\\" + _lotid + "-" + slidesList[i] + ".txt";//暂时使用CP1}
                        var backfilePath = CItems.FtpAddress + "\\BACKUP\\CP1\\" + _lotid + "-" + slidesList[i] + ".txt";//暂时使用CP1
                        if (File.Exists(backfilePath))
                            File.Delete(backfilePath);
                        File.Copy(filePath, backfilePath);
                        File.Delete(filePath);
                    }
                    #endregion
                    #region  F2
                    //for (int i = 0; i < slidesList.Length; i++)
                    //{
                    //    if (string.IsNullOrEmpty(slidesList[i]?.ToString()))
                    //        continue;
                    //    if (!Directory.Exists("\\\\10.190.221.100\\eda_f2_sx\\mes\\BACKUP"))
                    //        Directory.CreateDirectory(CItems.FtpAddress + "\\BACKUP");
                    //    var _lotid = lotID.Split('-')[0].ToString();
                    //    if (_lotid.Contains('.'))
                    //        _lotid = _lotid.Split('.')[0].ToString();
                    //    var filePath = CItems.FtpAddress + "\\CP\\" + _lotid + "-" + slidesList[i] + ".txt";
                    //    var backfilePath = "\\\\10.190.221.100\\eda_f2_sx\\mes\\BACKUP" + _lotid + "-" + slidesList[i] + ".txt";
                    //    if (File.Exists(backfilePath))
                    //        File.Delete(backfilePath);
                    //    File.Copy(filePath, backfilePath);
                    //    File.Delete(filePath);
                    //}
                    #endregion

                }
                catch (Exception ex)
                {
                    HoldRuningLot(xfwArgs);
                    CimLogger.Information($"TrackOut-FileBackUp:{ex.ToString()}");
                }

                //Dict.Current.lotInfo = new LotInfo();
                xfwArgs.Header[CItems.TrackOutReturnCode] = "0";
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.SaveTest() Execute Error.");
            }
        }

        private TrackOutResponse TrackOutMark(TrackOutResponse result, SMECMESClient mesClient, string facilityId, string userName, string eqpid, string lotID, string jsonvalue)
        {
            try
            {
                if (CItems.TrackOutPl > 0 && CItems.TrackOutTotal > 0)
                {
                    int totalTime = CItems.TrackOutTotal;
                    int currentTime = 0;
                    while (true)
                    {
                        if (currentTime >= totalTime)
                        {
                            var messages = TranslateMsg.GetTranslation("TrackOutStop", lotID, CItems.TrackOutTotal);
                            ClientService.ShowMessage(eqpid, MessageType.Info, messages, MessageOrigin.MES);
                            CimLogger.Information($"{Name}.TrackOutMark() :EAP>批次{lotID}已循环出站{CItems.TrackOutTotal}分钟，结束出站");
                            return result;
                        }
                        if (result.msg.Contains("RUNNINGHOLD") || result.msg.Contains("status is invalid"))
                        {
                            //将lot存放在缓存中，后续可以存储在DB或文件中，以防止EAP重启缓存丢失
                            if (!CItems.TrackOutList.Keys.Contains(lotID))
                            {
                                CItems.TrackOutList.TryAdd(lotID, JsonConvert.SerializeObject(new
                                {
                                    facilityId = facilityId,
                                    userName = userName,
                                    eqpid = eqpid,
                                    lotID = lotID,
                                    jsonvalue = jsonvalue,
                                    Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                                }));
                            }

                        }
                        else
                        {
                            CimLogger.Information($"{Name}.TrackOutMark() :MSG=:{result.msg}");
                            //出站原因不需要循环调用
                            return result;
                        }

                    }
                }
                else
                {
                    var messages = TranslateMsg.GetTranslation("TrackOutErr");
                    ClientService.ShowMessage(eqpid, MessageType.Info, messages, MessageOrigin.MES);
                    CimLogger.Information($"{Name}.TrackOutMark() EAP>配置项TrackOutPl或TrackOutTotal不存在");

                    return result;
                }
            }
            catch (Exception ex)
            {
                CimLogger.Error($"{Name}.TrackOutMark() :ERR:{ex.Message}");
                return result;
            }
        }

        public void TrackOutStart(XfwArgs xfwArgs)
        {
            try
            {
                if (CItems.timer == null)
                {
                    if (CItems.TrackOutPl <= 0)
                    {
                        CItems.TrackOutPl = 10;
                    }
                    CItems.timer = new System.Timers.Timer();
                    CItems.timer.Enabled = true;
                    CItems.timer.Interval = CItems.TrackOutPl * 1000 * 60; //执行间隔时间,单位为毫秒; 这里实际间隔为分钟
                    CItems.timer.Start();
                    CItems.timer.Elapsed += TrackOutWhile;
                }

            }
            catch (Exception ex)
            {
                XfwContext.EapLogger.Error(ex, $"EapService.Daytime() Execute Error.");
            }
        }
        public void TrackOutWhile(object source, System.Timers.ElapsedEventArgs b)
        {
            if (CItems.TrackOutList.Count == 0)
            {
                return;
            }
            SMECMESClient mesClient = new SMECMESClient();
            foreach (var item in CItems.TrackOutList.Keys)
            {
                var lotinfo = JsonConvert.DeserializeObject<TrackOutPara>(CItems.TrackOutList[item]);
                var messages = TranslateMsg.GetTranslation("TrackOutFail", CItems.TrackOutPl);

                //Thread.Sleep(1000 * 60 * CItems.TrackOutPl);
                int min = (int)Math.Round((DateTime.Now - lotinfo.Time).TotalMinutes);
                //移除超时的数据
                if (CItems.TrackOutTotal < min)
                {
                    CItems.TrackOutList.TryRemove(item, out string _lotinfo);
                    messages = TranslateMsg.GetTranslation("TrackOutStop", lotinfo.lotID, CItems.TrackOutTotal);
                    ClientService.ShowMessage(lotinfo.eqpid, MessageType.Info, messages, MessageOrigin.MES);
                    CimLogger.Information($"{Name}.TrackOutMark() 批次{lotinfo.lotID}已循环出站{CItems.TrackOutTotal}分钟，结束出站");

                    continue;
                }

                var result = mesClient.dispatchLotOut(lotinfo.facilityId, lotinfo.userName, lotinfo.eqpid, lotinfo.lotID, lotinfo.jsonvalue);
                if (!string.IsNullOrEmpty(CItems.TrackOutFailInfo))
                {
                    var msgs = CItems.TrackOutFailInfo.Split(';');
                    bool isFalg = false;
                    foreach (var row in msgs)
                    {
                        if (result.msg.Contains(row))
                        {
                            isFalg = true;
                            break;
                        }
                    }
                    if (isFalg)
                    {
                        messages = TranslateMsg.GetTranslation("TrackOutFail", CItems.TrackOutPl, CItems.TrackOutTotal - min, lotinfo.lotID);
                        ClientService.ShowMessage(lotinfo.eqpid, MessageType.Info, messages, MessageOrigin.MES);
                        CimLogger.Information($"{Name}.TrackOutMark() :trackout fail err info :{result.msg} ,批次{lotinfo.lotID}将在{CItems.TrackOutPl}分钟后再次调用出站，剩余出站时间{CItems.TrackOutTotal - min}分钟。");
                    }
                    else
                    {
                        CimLogger.Information($"{Name}.TrackOutMark() :Lotid={lotinfo.eqpid},MSG=:{result.msg}；MES返回结果不在监控列表中，移除此批次自动出站");
                        //出站原因不需要循环调用
                        CItems.TrackOutList.TryRemove(item, out string _lotinfo);
                    }
                }
            }

        }
        /// <summary>
        /// MES出站
        /// </summary>
        /// <param name="rptRunHisTemp"></param>
        /// <returns></returns>
        public int TrackOut(RPT_RUN_HISTORY_TEMP rptRunHisTemp)
        {
            int resultOut = 0;
            try
            {
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    resultOut = -2;
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(rptRunHisTemp.EQP_ID, MessageType.Info, message, MessageOrigin.MES);
                    return resultOut;
                }
                int count = 0;
                if (Dict.Current.LotOutNum.ContainsKey(rptRunHisTemp.LOT_ID))
                {
                    count = Dict.Current.LotOutNum[rptRunHisTemp.LOT_ID];
                }
                string msg = "";
                Dictionary<string, string> messages = null;
                var messageType = MessageType.Info;
                SMECMESClient mesClient = new SMECMESClient();
                var listbaseInfo = new List<BaseInfo>();
                BaseInfo baseInfo = new BaseInfo();
                LotBaseInfo lotbaseInfo = new LotBaseInfo();
                lotbaseInfo.chamberType = "";
                lotbaseInfo.lotId = rptRunHisTemp.LOT_ID;
                lotbaseInfo.ppid = rptRunHisTemp.PROBER_RECIPE;
                lotbaseInfo.recipeLogicalRrn = rptRunHisTemp.RECIPE_LOGICAL_RRN;
                lotbaseInfo.reticleGroupId = rptRunHisTemp.RETICLE_GROUP_ID;
                lotbaseInfo.reticleGroupRrn = rptRunHisTemp.RETICLE_GROUP_RRN;
                lotbaseInfo.trackFlag = "out";
                baseInfo.lotBaseInfo = lotbaseInfo;
                listbaseInfo.Add(baseInfo);
                var jsonvalue = JsonConvert.SerializeObject(listbaseInfo);
                var result = mesClient.dispatchLotOut(rptRunHisTemp.FACILITY_ID, rptRunHisTemp.OPERATOR_ID, rptRunHisTemp.EQP_ID, rptRunHisTemp.LOT_ID, jsonvalue);
                if (result == null)
                {
                    resultOut = -1;
                    messageType = MessageType.Error;
                    messages = TranslateMsg.GetTranslation(CItems.MESTrackOutNG, rptRunHisTemp.LOT_ID, " Interface Timeout");
                    msg = string.Format($"出站失败，接口超时，还剩下{count}次");
                    CimLogger.Information($"{Name}.TrackOut(RPT_RUN_HISTORY_TEMP) lot:{rptRunHisTemp.LOT_ID}，{msg}");

                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    if (result.msg == "Lot already trackout")
                    {
                        resultOut = 1;
                        messageType = MessageType.Error;
                        messages = new Dictionary<string, string>();
                        messages.Add("EN", rptRunHisTemp.LOT_ID + "," + result.msg);
                        messages.Add("CN", rptRunHisTemp.LOT_ID + "," + result.msg);
                        msg = result.msg;
                        CimLogger.Information($"{Name}.TrackOut(RPT_RUN_HISTORY_TEMP) lot:{rptRunHisTemp.LOT_ID} ,{result.msg}");
                    }
                    else
                    {
                        resultOut = -1;
                        messageType = MessageType.Error;
                        messages = TranslateMsg.GetTranslation(CItems.MESTrackOutNG, rptRunHisTemp.LOT_ID, result.msg);
                        msg = string.Format($"出站失败，{result.msg}，还剩下{count}次");
                        CimLogger.Information($"{Name}.TrackOut(RPT_RUN_HISTORY_TEMP) lot:{rptRunHisTemp.LOT_ID} ,{msg}");
                    }

                }
                else
                {
                    resultOut = 0;
                    messageType = MessageType.Info;
                    messages = TranslateMsg.GetTranslation(CItems.MESTrackOutOK, rptRunHisTemp.LOT_ID);
                    msg = string.Format("出站成功");
                    CimLogger.Information($"{Name}.TrackOut(RPT_RUN_HISTORY_TEMP) lot:{rptRunHisTemp.LOT_ID}，{msg}");

                }
                //dbServer.InsertMsgInfo(msg, rptRunHisTemp.EQP_ID, rptRunHisTemp.LOT_ID);
                if (messages != null && messages.Count != 0)
                {
                    ClientService.ShowMessage(rptRunHisTemp.EQP_ID, messageType, messages, MessageOrigin.EAP);
                }
                return resultOut;
            }
            catch (Exception ex)
            {
                CimLogger.Error(ex, $"{Name}.TrackOut(RPT_RUN_HISTORY_TEMP) Execute Error.");
                return -1;
            }

        }
        #endregion

        /// <summary>
        /// TrackIn结果
        /// </summary>
        public void TrackInResult(XfwArgs xfwArgs)
        {
            try
            {
                var eqpId = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var messages = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpId, MessageType.Info, messages, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackInResult() The EAP has been switched Automatic Operation");
                    return;
                }
                var returnCode = xfwArgs.Header[CItems.TrackInReturnCode]?.ToString();
                var message = xfwArgs.Header[CItems.TrackInMessage]?.ToString();

                xfwArgs.Header[CItems.MessageOrigin] = MessageOrigin.MES.ToString();
                if (returnCode == "0")
                {
                    //TrackIn成功，提示Client
                    xfwArgs.Header[CItems.MessageType] = MessageType.Info.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation(CItems.MESTrackInOK);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                    CimLogger.Information($"{Name}.TrackInResult() ：TrackIn 成功 .");
                    xfwArgs.SetReturnCodeOK();
                    return;
                }
                else
                {
                    //TrackIn失败，提示Client
                    xfwArgs.Header[CItems.MessageType] = MessageType.Error.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation(CItems.MESTrackInNG, message);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                    CimLogger.Information($"{Name}.TrackInResult() ：TrackIn 失败 .");
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackInResult() ：TrackIn 失败 .");
                    return;
                }
            }
            catch (Exception ex)
            {
                CimLogger.Error(ex, $"{Name}.TrackInResult() Execute Error.");
                xfwArgs.SetReturnCodeNG(ex.Message);
            }
        }


        /// <summary>
        /// TrackOut结果
        /// </summary>
        public void TrackOutResult(XfwArgs xfwArgs)
        {
            try
            {
                var eqpId = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var messages = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpId, MessageType.Info, messages, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOutResult() The EAP has been switched Automatic Operation");
                    return;
                }
                var returnCode = xfwArgs.Header[CItems.TrackOutReturnCode]?.ToString();
                var message = xfwArgs.Header[CItems.TerminalMessage]?.ToString();
                xfwArgs.Header[CItems.MessageOrigin] = MessageOrigin.MES.ToString();
                if (returnCode == "0")
                {
                    //MES "TrackOut" 成功，提示Client
                    xfwArgs.Header[CItems.MessageType] = MessageType.Info.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation(CItems.MESTrackOutOK, eqpId);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                    CimLogger.Information($"{Name}.TrackOutResult() ：TrackOut 成功.");
                }
                else
                {
                    //MES "TrackOut"失败，提示Client
                    xfwArgs.Header[CItems.MessageType] = MessageType.Error.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation(CItems.MESTrackOutNG, eqpId, message);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                    CimLogger.Information($"{Name}.TrackOutResult() ：TrackOut 失败.");
                }
            }
            catch (Exception ex)
            {
                CimLogger.Error(ex, $"{Name}.TrackOutResult() Execute Error.");
                xfwArgs.SetReturnCodeNG(ex.Message);
            }
        }

        /// <summary>
        /// 缓存批次信息
        /// </summary>
        /// <param name="xfwArgs"></param>
        public void CacheLotInfo(XfwArgs xfwArgs)
        {
            try
            {
                Dict.Current.lotInfo.lotId = xfwArgs.Header[CItems.LotID]?.ToString().Trim();
                Dict.Current.lotInfo.eqptID = xfwArgs.Header[CItems.EqpID]?.ToString().Trim();
                Dict.Current.lotInfo.lotType = xfwArgs.Header[CItems.lotType]?.ToString().Trim();
                Dict.Current.lotInfo.batchId = xfwArgs.Header[CItems.batchId]?.ToString().Trim();
                Dict.Current.lotInfo.operationId = xfwArgs.Header[CItems.operationId]?.ToString().Trim();
                Dict.Current.lotInfo.productId = xfwArgs.Header[CItems.productId]?.ToString().Trim();
                Dict.Current.lotInfo.qty1 = xfwArgs.Header[CItems.WaferQty]?.ToString().Trim();
                Dict.Current.lotInfo.UnitList = xfwArgs.Header[CItems.UnitList] as List<Core.unitsInfo>;
                Dict.Current.lotInfo.ppid = xfwArgs.Header[CItems.ppid]?.ToString().Trim();
                Dict.Current.lotInfo.recipeLogicalRrn = xfwArgs.Header[CItems.recipeLogicalRrn]?.ToString().Trim();
                Dict.Current.lotInfo.reticleGroupId = xfwArgs.Header[CItems.reticleGroupId]?.ToString().Trim();
                Dict.Current.lotInfo.reticleGroupRrn = xfwArgs.Header[CItems.reticleGroupRrn]?.ToString().Trim();
                Dict.Current.lotInfo.testerProgram = xfwArgs.Header[CItems.TestProgram]?.ToString().Trim();
                Dict.Current.lotInfo.proberRecipe = xfwArgs.Header[CItems.ProberRecipe]?.ToString().Trim();
                Dict.Current.lotInfo.userName = xfwArgs.Header[CItems.UserName]?.ToString().Trim();
                Dict.Current.lotInfo.customerLotId = xfwArgs.Header[CItems.CustomerLotId]?.ToString().Trim();
                Dict.Current.lotInfo.ProberCardId = xfwArgs.Header[CItems.ProberCardId]?.ToString().Trim();
                Dict.Current.lotInfo.lotStatus = xfwArgs.Header[CItems.lotStatus]?.ToString();
                Dict.Current.lotInfo.rcflag = xfwArgs.Header[CItems.rcflag]?.ToString();
                Dict.Current.lotInfo.creatTime = DateTime.Now;
                CimLogger.Information($"进站时间：{DateTime.Now},设备：{Dict.Current.lotInfo.eqptID},批次：{Dict.Current.lotInfo.lotId}");
                CimLogger.Information($"{Name}.CacheLotInfo() ：批次信息缓存成功.");


                RPT_RUN_HISTORY_TEMP rptRunHisTemp = new RPT_RUN_HISTORY_TEMP();
                rptRunHisTemp.CUSTOMER_LOT_ID = Dict.Current.lotInfo.customerLotId;
                rptRunHisTemp.EQP_ID = Dict.Current.lotInfo.eqptID;
                rptRunHisTemp.LOT_ID = Dict.Current.lotInfo.lotId;
                rptRunHisTemp.OPERATOR_ID = Dict.Current.lotInfo.userName;
                rptRunHisTemp.PROBER_RECIPE = Dict.Current.lotInfo.proberRecipe;
                rptRunHisTemp.PRODUCT_ID = Dict.Current.lotInfo.productId;
                rptRunHisTemp.TESTER_PROGRAM = Dict.Current.lotInfo.testerProgram;
                rptRunHisTemp.TRACKIN_TIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                rptRunHisTemp.WAFER_QTY = Dict.Current.lotInfo.qty1;
                rptRunHisTemp.RECIPE_LOGICAL_RRN = Dict.Current.lotInfo.recipeLogicalRrn;
                rptRunHisTemp.RETICLE_GROUP_ID = Dict.Current.lotInfo.reticleGroupId;
                rptRunHisTemp.RETICLE_GROUP_RRN = Dict.Current.lotInfo.reticleGroupRrn;
                rptRunHisTemp.FACILITY_ID = Dict.Current.lotInfo.facilityId;
                rptRunHisTemp.PPID = Dict.Current.lotInfo.ppid;
                rptRunHisTemp.PROBERCARDID = Dict.Current.lotInfo.ProberCardId;
                dbServer.InsertRunHisTemp(rptRunHisTemp);
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.CacheLotInfo() Execute Error.");
            }
        }
        /// <summary>
        /// EAP->MES 自动hold批次
        /// </summary>
        /// <param name="xfwArgs"></param>
        public void HoldLot(XfwArgs xfwArgs)
        {
            try
            {
                var eqpid = Dict.Current.lotInfo.eqptID;
                if (string.IsNullOrEmpty(eqpid))
                    eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOut() The EAP has been switched Automatic Operation");
                    return;
                }
                var lotID = Dict.Current.lotInfo.lotId;
                if (string.IsNullOrEmpty(lotID))
                    lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                var userName = Dict.Current.lotInfo.userName;
                if (string.IsNullOrEmpty(userName))
                    userName = xfwArgs.Header[CItems.UserName]?.ToString();
                var facilityId = Dict.Current.lotInfo.facilityId;
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                CimLogger.Information($"HoldLot:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                var group = "YE";
                var groupCode = "YE_TE_OTHER";
                var reasons = xfwArgs.Header[CItems.Reasons]?.ToString();
                xfwArgs.Header[CItems.EqpID] = eqpid;
                SMECMESClient mesClient = new SMECMESClient();
                var result = mesClient.holdMixrunLot(facilityId, userName, eqpid, lotID, group, groupCode, reasons);
                if (result == null)
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.SetReturnCodeNG("HoldLot: HoldLot==null");
                    return;
                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG("HoldLot: result.success==False");
                    return;
                }
                xfwArgs.Header[CItems.HoldLotReturnCode] = "0";
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.HoldLot() Execute Error.");
            }
        }
        public void HoldLotMFG(XfwArgs xfwArgs)
        {
            try
            {
                var eqpid = Dict.Current.lotInfo.eqptID;
                if (string.IsNullOrEmpty(eqpid))
                    eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOut() The EAP has been switched Automatic Operation");
                    return;
                }
                var lotID = Dict.Current.lotInfo.lotId;
                if (string.IsNullOrEmpty(lotID))
                    lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                var userName = Dict.Current.lotInfo.userName;
                if (string.IsNullOrEmpty(userName))
                    userName = xfwArgs.Header[CItems.UserName]?.ToString();
                var facilityId = Dict.Current.lotInfo.facilityId;
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                CimLogger.Information($"HoldLot:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                var group = "MFG_BGBM";
                var groupCode = "MFG_BGBM_OTHERS";

                var reasons = xfwArgs.Header[CItems.Reasons]?.ToString();
                xfwArgs.Header[CItems.EqpID] = eqpid;
                SMECMESClient mesClient = new SMECMESClient();
                var result = mesClient.holdMixrunLot(facilityId, userName, eqpid, lotID, group, groupCode, reasons);
                if (result == null)
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.SetReturnCodeNG("HoldLot: HoldLot==null");
                    return;
                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG("HoldLot: result.success==False");
                    return;
                }
                xfwArgs.Header[CItems.HoldLotReturnCode] = "0";
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.HoldLot() Execute Error.");
            }
        }
        public void HoldLotF2(XfwArgs xfwArgs)
        {
            try
            {
                var eqpid = Dict.Current.lotInfo.eqptID;
                if (string.IsNullOrEmpty(eqpid))
                    eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOut() The EAP has been switched Automatic Operation");
                    return;
                }
                var lotID = Dict.Current.lotInfo.lotId;
                if (string.IsNullOrEmpty(lotID))
                    lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                var userName = Dict.Current.lotInfo.userName;
                if (string.IsNullOrEmpty(userName))
                    userName = xfwArgs.Header[CItems.UserName]?.ToString();
                var facilityId = Dict.Current.lotInfo.facilityId;
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                CimLogger.Information($"HoldLot:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                var group = "MFG_BGBM";
                var groupCode = "MFG_BGBM_OTHERS";

                if (facilityId == "F2")
                {
                    group = "TE";
                    groupCode = "TE_OTHERS";
                }
                var reasons = xfwArgs.Header[CItems.Reasons]?.ToString();
                xfwArgs.Header[CItems.EqpID] = eqpid;
                SMECMESClient mesClient = new SMECMESClient();
                var result = mesClient.holdMixrunLot(facilityId, userName, eqpid, lotID, group, groupCode, reasons);
                if (result == null)
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.SetReturnCodeNG("HoldLot: HoldLot==null");
                    return;
                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG("HoldLot: result.success==False");
                    return;
                }
                xfwArgs.Header[CItems.HoldLotReturnCode] = "0";
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.HoldLot() Execute Error.");
            }
        }
        /// <summary>
        /// EAP->MES 自动hold批次
        /// </summary>
        /// <param name="xfwArgs"></param>
        public void HoldRuningLot(XfwArgs xfwArgs)
        {
            try
            {
                var eqpid = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var message = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpid, MessageType.Info, message, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.TrackOut() The EAP has been switched Automatic Operation");
                    return;
                }
                var lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                if (string.IsNullOrEmpty(lotID))
                {
                    xfwArgs.Header[CItems.TrackOutReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = "HoldRuningLot: lotid==null";
                    xfwArgs.SetReturnCodeNG("HoldRuningLot: lotid==null");
                    return;
                }
                var userName = xfwArgs.Header[CItems.UserName]?.ToString();
                if (string.IsNullOrEmpty(userName))
                    userName = Dict.Current.lotInfo.userName;
                var facilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                if (string.IsNullOrEmpty(facilityId))
                    facilityId = Dict.Current.lotInfo.facilityId;
                CimLogger.Information($"HoldRuningLot:eqpid:{eqpid},lotID:{lotID},userName:{userName},facilityId:{facilityId}");
                var group = "YE";
                var groupCode = "YE_TE_OTHER";
                var reasons = xfwArgs.Header[CItems.Reasons]?.ToString();
                xfwArgs.Header[CItems.EqpID] = eqpid;
                SMECMESClient mesClient = new SMECMESClient();
                var result = mesClient.holdRuningLot(facilityId, userName, eqpid, lotID, group, groupCode, reasons);
                //holdlot后清空字典
                CItems.lotParamDic.Remove(lotID);
                CItems.waferInfoDic = new Dictionary<string, string>();
                if (result == null)
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.SetReturnCodeNG("HoldLot: HoldLot==null");
                    return;
                }
                else if (result.success.ToUpper() == "FALSE")
                {
                    xfwArgs.Header[CItems.HoldLotReturnCode] = "1";
                    xfwArgs.Header[CItems.TerminalMessage] = result.msg;
                    xfwArgs.SetReturnCodeNG("HoldLot: result.success==False");
                    return;
                }
                xfwArgs.Header[CItems.HoldLotReturnCode] = "0";
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                xfwArgs.SetReturnCodeNG(ex.Message);
                CimLogger.Error(ex, $"{Name}.HoldLot() Execute Error.");
            }
        }

        /// <summary>
        /// holdlot 结果
        /// </summary>
        /// <param name="xfwArgs"></param>
        public void HoldLotResult(XfwArgs xfwArgs)
        {
            try
            {
                var eqpId = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (Dict.Current.EAPRunMode == RunMode.ManualOperation)
                {
                    var messages = TranslateMsg.GetTranslation(CItems.ManualOperation);
                    ClientService.ShowMessage(eqpId, MessageType.Info, messages, MessageOrigin.MES);
                    xfwArgs.SetReturnCodeNG($"{Name}.HoldLotResult() The EAP has been switched Automatic Operation");
                    return;
                }
                var returnCode = xfwArgs.Header[CItems.HoldLotReturnCode]?.ToString();
                var message = xfwArgs.Header[CItems.TerminalMessage]?.ToString();

                xfwArgs.Header[CItems.MessageOrigin] = MessageOrigin.MES.ToString();
                CimLogger.Information($"HoldLotResult:{eqpId},TerminalMessage:{message}");

                if (returnCode == "0")
                {
                    //HoldLot成功，提示Client
                    xfwArgs.Header[CItems.MessageType] = MessageType.Info.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation(CItems.MESHoldLotOK);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                    CimLogger.Information($"{Name}.HoldLotResult() ：HoldLot成功 .");
                    xfwArgs.SetReturnCodeOK();
                    return;
                }
                else
                {
                    //HoldLot失败，提示Client
                    xfwArgs.Header[CItems.MessageType] = MessageType.Error.ToString();
                    Dictionary<string, string> msgs = TranslateMsg.GetTranslation(CItems.MESHoldLotNG, message);
                    xfwArgs.Header[CItems.TerminalMessage] = msgs;
                    CimLogger.Information($"{Name}.HoldLotResult() ：HoldLot 失败 .");
                    xfwArgs.SetReturnCodeNG($"{Name}.HoldLotResult() ：HoldLot 失败 .");
                    return;
                }
            }
            catch (Exception ex)
            {
                CimLogger.Error(ex, $"{Name}.HoldLotResult() Execute Error.");
                xfwArgs.SetReturnCodeNG(ex.Message);
            }
        }

        /// <summary>
        /// 获取FTP中Wafer信息 结果
        /// </summary>
        /// <param name="xfwArgs"></param>
        public void CheckWafer(XfwArgs xfwArgs)
        {
            try
            {

                var eqpID = xfwArgs.Header[CItems.EqpID]?.ToString();
                if (string.IsNullOrEmpty(eqpID))
                    eqpID = Dict.Current.lotInfo.eqptID;
                var FacilityId = xfwArgs.Header[CItems.FacilityId]?.ToString();
                if (string.IsNullOrEmpty(FacilityId))
                    FacilityId = Dict.Current.lotInfo.facilityId;
                var UserName = xfwArgs.Header[CItems.UserName]?.ToString();
                if (string.IsNullOrEmpty(UserName))
                    UserName = Dict.Current.lotInfo.userName;
                var lotID = xfwArgs.Header[CItems.LotID]?.ToString();
                if (string.IsNullOrEmpty(lotID))
                    lotID = Dict.Current.lotInfo.lotId;
                //lotID = "EAP01";
                var createTime = xfwArgs.Header[CItems.CreateTime]?.ToString();//获取批次进站时间
                if (string.IsNullOrEmpty(createTime))
                    createTime = Dict.Current.lotInfo.creatTime.ToString();
                //createTime = "2023/4/4 11:11:42";
                var waferId = xfwArgs.Header[CItems.waferId]?.ToString().Split(';');//获取waferid

                var slidesInfo = "";//获取出站片号List
                if (waferId != null)
                {
                    for (int i = 0; i < waferId.Length; i++)
                    {
                        if (!string.IsNullOrEmpty(waferId[i]))
                            slidesInfo += waferId[i].Split('-')[1].ToString() + ";";
                    }
                }

                if (!string.IsNullOrEmpty(slidesInfo))
                    slidesInfo = slidesInfo.Substring(0, slidesInfo.Length - 1);
                xfwArgs.Header[CItems.slidesInfo] = slidesInfo;
                var slidesList = slidesInfo.Split(';');



                CimLogger.Information($"进站时间：{createTime},lotID：{lotID},位置号：{slidesInfo},数量：{Dict.Current.lotInfo.waferList.Count}");

                if (string.IsNullOrEmpty(createTime) || string.IsNullOrEmpty(lotID) || string.IsNullOrEmpty(slidesInfo))
                {
                    xfwArgs.SetReturnCodeNG("");
                    CimLogger.Information($"CheckWaferTry");
                    var messages = TranslateMsg.GetTranslation("CheckWaferTry");
                    ClientService.ShowMessage(Dict.Current.TesterID, MessageType.Alarm, messages, MessageOrigin.OCR);
                    return;
                }
                mvOutParameterSet parameterInfo = new mvOutParameterSet();
                var lotParamStr = "";
                if (CItems.lotParamDic.ContainsKey(lotID))
                    lotParamStr = CItems.lotParamDic[lotID];
                if (!string.IsNullOrEmpty(lotParamStr))
                    parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotParamStr);
                xfwArgs.Header[CItems.LotID] = lotID;
                xfwArgs.Header[CItems.EqpID] = eqpID;
                xfwArgs.Header[CItems.FacilityId] = FacilityId;
                xfwArgs.Header[CItems.UserName] = UserName;
                //if (CItems.IsTest == "true")
                //{
                //    xfwArgs.SetReturnCodeOK();
                //    return;
                //}
                //Map文件不存在则直接返回，退出本次出站
                var mapFile = "";
                foreach (var wafer in Dict.Current.lotInfo.waferList)
                {
                    var filePath = CItems.FtpAddress + "\\CP\\CP1\\" + wafer.waferId + ".txt";//暂时使用CP1----F1
                    CimLogger.Information($"批次：{lotID},文件路径:{filePath}");
                    var date = DateTime.Now;
                    var res = false;
                    int CheckFile = CItems.CheckFile;
                    if (CheckFile <= 0)
                    {
                        CheckFile = 60;
                    }
                    while (true)
                    {
                        if ((DateTime.Now - date).TotalMinutes < CheckFile)
                        {
                            var waferPath = File.Exists(filePath);
                            if (waferPath)
                            {
                                //var fileCreateTime = File.GetCreationTime(filePath);//文件创建时间
                                //if (DateTime.Parse(createTime) < fileCreateTime)
                                //{
                                mapFile = File.ReadAllText(filePath);
                                if (!string.IsNullOrEmpty(mapFile))
                                    break;
                                //}
                            }
                            else
                            {
                                CimLogger.Information("等待1分钟，文件未找到：" + filePath);
                                Thread.Sleep(60000);
                                mapFile = "";
                            }
                        }
                        else
                        {
                            xfwArgs.Header[CItems.Reasons] = $"LOTID:{lotID}, filePath:{filePath} is not found!";
                            xfwArgs.Header[CItems.lotStatus] = "HoldLot";
                            CimLogger.Information("已查找" + CheckFile.ToString() + "分钟，文件：" + filePath + "未找到！");
                            return;
                        }
                    }
                    //判断读取出来的文件内容是否为null
                    if (!string.IsNullOrEmpty(mapFile))
                        res = checkPassDie(mapFile, wafer.waferId, wafer.passNo);//比对PassDie方法
                    if (!res)
                    {
                        CimLogger.Information("PassDie数量比对未通过，执行HoldLot");
                        xfwArgs.Header[CItems.Reasons] = $"LOTID:{lotID}, waferId:{waferId} PassDie Count not equal,lot hold!";
                        xfwArgs.Header[CItems.lotStatus] = "HoldLot";
                        return;
                    }
                }
                CimLogger.Information("CheckWafer正常退出，执行TrackOut!");
                xfwArgs.SetReturnCodeOK();
            }
            catch (Exception ex)
            {
                CimLogger.Error(ex, $"{Name}.CheckWafer() Execute Error.");
                xfwArgs.SetReturnCodeNG(ex.Message);
            }
        }



        //更新批次良率信息，成功则代表共享盘文件已全部查找成功
        public bool CheckMapFileExist(LotInfo lotInfo)
        {
            try
            {
                var lotID = lotInfo.lotId;
                foreach (var wafer in lotInfo.waferList)
                {
                    //公共盘map对应文件名称不包含cheksum
                    var waferId = wafer.waferId.Split("-")[0] + "-" + wafer.waferId.Split("-")[1];
                    var filePath = CItems.FtpAddress + "\\CP\\CP1\\" + waferId + ".txt";//暂时使用CP1----F1
                    var waferPath = System.IO.File.Exists(filePath);
                    if (!waferPath)
                    {
                        TrackoutLogger.Information(string.Format($"路径下没有找到Map文件，路径：{filePath}"));
                        return false;
                    }
                }
            }
            catch (Exception ex)
            {
                TrackoutLogger.Error(ex, $"{Name}.CheckMapFileExist() Execute Error.");
                return false;
            }
            return true;
        }

        public bool CheckXlsxFileExist(LotInfo lotInfo)
        {
            var productToPath = new Dictionary<string, string>()
        {
            { "1491A", "\\\\10.190.221.100\\eda_ods_sx\\Ray_CP_Data\\result\\A066-U01\\1491A\\Leakage" },
            { "2771A", "\\\\10.190.221.100\\eda_ods_sx\\Ray_CP_Data\\result\\A066-U01\\2771A\\Leakage" },
            {"0418C", "\\\\10.190.221.100\\eda_ods_sx\\Ray_CP_Data\\result\\A066-U01\\0418C\\Leakage" },
            {"1940B", "\\\\10.190.221.100\\eda_ods_sx\\Ray_CP_Data\\result\\A066-U01\\1940B\\ASAMLeak" },
            {"3121A", "\\\\10.190.221.100\\eda_ods_sx\\Ray_CP_Data\\result\\A066-U01\\3121A\\Leakage2"},
        };
            try
            {
                string directoryPath = productToPath[lotInfo.productId];
                if (lotInfo.testerProgram.Contains("_CF_") && lotInfo.productId == "0418C")
                {
                    directoryPath = "\\\\10.190.221.100\\eda_ods_sx\\Ray_CP_Data\\result\\A066-U01\\0418C\\FR";

                }
                if (lotInfo.testerProgram.Contains("_LEAK3_") && lotInfo.productId == "1940B")
                {
                    directoryPath = "\\\\10.190.221.100\\eda_ods_sx\\Ray_CP_Data\\result\\A066-U01\\1940B\\Leakage3";
                }
                if (string.IsNullOrEmpty(directoryPath))
                {
                    TrackoutLogger.Information(string.Format($"该产品类型对应出账逻辑未配置，：{lotInfo.productId}"));
                    return false;
                }
                foreach (var wafer in lotInfo.waferList)
                {
                    var waferId1 = wafer.waferId.Split("-")[0] + "_" + wafer.waferId.Split("-")[1];
                    var waferId2 = wafer.waferId.Split("-")[1] + "_" + wafer.waferId.Split("-")[0];

                    if (CItems.IsTest == "true")
                    {
                        directoryPath = "\\\\127.0.0.1\\cp1\\CP\\CP1";
                    }
                    var matchingFiles = System.IO.Directory.GetFiles(directoryPath, "*.xls")
                                             .Where(file => Path.GetFileName(file).Contains(waferId1) || Path.GetFileName(file).Contains(waferId2))
                                             .OrderByDescending(file => System.IO.File.GetCreationTime(file))
                                             .ToArray();
                    if (matchingFiles == null || matchingFiles.Count() == 0)
                    {
                        TrackoutLogger.Information(string.Format($"路径{directoryPath}未找到文件名称包含{waferId1}或{waferId2}的文件"));
                        return false;
                    }
                    else if (new FileInfo(matchingFiles[0]).LastWriteTime < lotInfo.creatTime || new FileInfo(matchingFiles[0]).CreationTime < lotInfo.creatTime)
                    {
                        TrackoutLogger.Information(string.Format($"路径{directoryPath}下最新文件{new FileInfo(matchingFiles[0]).FullName}创建时间与修改时间小于批次创建时间：{lotInfo.creatTime}"));
                        return false;
                    }
                    else
                    {

                        saveWaferParam(wafer, matchingFiles[0]);
                        TrackoutLogger.Information(string.Format($"wafer{waferId1}保存参数成功,文件为{new FileInfo(matchingFiles[0]).Name}"));
                    }

                }
            }
            catch (Exception ex)
            {
                TrackoutLogger.Information(ex, $"{Name}.CheckMapFileExist() Execute Error.");
                return false;
            }
            return true;
        }

        private void saveWaferParam(Wafer wafer, string xlsPath)
        {
            TrackoutLogger.Information(string.Format($"waferID{wafer.waferId}收值文件为{xlsPath}"));
            // 打开文件流  
            using (FileStream fileStream = new FileStream(xlsPath, FileMode.Open, FileAccess.Read))
            {
                // 根据文件扩展名选择工作簿类型  
                IWorkbook workbook;
                if (Path.GetExtension(xlsPath).ToLower() == ".xls")
                {
                    workbook = new HSSFWorkbook(fileStream); // 用于 XLS 文件  
                }
                else
                {
                    workbook = new XSSFWorkbook(fileStream); // 用于 XLSX 文件  
                }

                // 获取第一个工作表  
                ISheet sheet = workbook.GetSheetAt(0);

                // 获取列数
                int lastColumnNum = sheet.GetRow(12).LastCellNum;
                wafer.valueMap = new Dictionary<string, ArrayList>();
                // 遍历列 ,起始坐标13 C
                for (int col = 2; col < lastColumnNum; col++)
                {
                    //设置参数名称
                    if (sheet.GetRow(12) != null && sheet.GetRow(12).GetCell(col) != null && sheet.GetRow(12).GetCell(col).ToString() != "SITE")
                    {
                        var valueKey = sheet.GetRow(12).GetCell(col).ToString();
                        var valueList = new ArrayList();
                        for (int row = 13; row <= sheet.LastRowNum; row++)
                        {
                            var value = sheet.GetRow(row).GetCell(col).ToString();
                            // 将字符串转换为double  
                            if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out double number))
                            {
                                valueList.Add(number.ToString("F3", CultureInfo.InvariantCulture));
                            }
                            else
                            {
                                TrackoutLogger.Information("字符串无法转换为double。");
                            }
                        }
                        wafer.valueMap.Add(valueKey.ToUpper(), valueList);
                    }
                }

                // 关闭工作簿  
                workbook.Close();
            }

        }


        private bool IsProcessWafer(LotInfo lotInfo, Wafer wafer)
        {
            var selectWaferPosistion = lotInfo.LotLists.Split("-")[0].Split(";");
            if (selectWaferPosistion.Contains(wafer.postion))
            {
                return true;
            }
            return false;
        }

        public bool updateWaferYield(LotInfo lotInfo)
        {

            var parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotInfo.parameterSet);
            foreach (var item in parameterInfo.parameters)
            {
                //此处存疑，目前看所有更新的参数都是良率，为什么不写死Yield?
                var parameterId = item.parameterId.Split('-');
                var paraName = parameterId[parameterId.Length - 1].ToString();
                foreach (var item1 in item.samplePrompts)
                {
                    //此处以waferId + 下划线 + 参数名称命名，在解析公共盘是否存在文件文件时会将解析结果放到lot信息缓存里
                    var name = item1.unitId.Replace("#", "-").ToString() + "_" + paraName;
                    var paraValue = lotInfo.waferInfoDic.ContainsKey(name);
                    foreach (var item2 in item1.readingPrompts)
                    {
                        if (paraValue)
                        {
                            if (lotInfo.waferInfoDic[name].ToString().Contains("%")){
                                string val = lotInfo.waferInfoDic[name].ToString().Replace("%", "");
                                if (string.IsNullOrEmpty(val))
                                {
                                    TrackoutLogger.Information("name：" + name + "对应值为空，停止出账");
                                    return false;
                                }
                                else
                                {
                                    double dataValue = double.Parse(val);
                                    if (dataValue > 0 || dataValue < 0)
                                        item2.dataValue = Math.Round((dataValue / 100.00), 4).ToString();
                                    else
                                        item2.dataValue = "0";
                                }
                            }
                            else {
                                if (string.IsNullOrEmpty(lotInfo.waferInfoDic[name].ToString()))
                                {
                                    TrackoutLogger.Information("name：" + name + "对应值为空，停止出账");
                                    return false;
                                }
                                else
                                {
                                   item2.dataValue = lotInfo.waferInfoDic[name].ToString();
                                }

                            }
                            
                        }
                        else
                        {
                            TrackoutLogger.Information("name：" + name + "对应值不存在，停止出账");
                            return false;
                        }
                    }
                }
            }
            lotInfo.parameterSet = JsonConvert.SerializeObject(parameterInfo);
            return true;
        }

        public bool updateWaferValue(LotInfo lotInfo)
        {

            var parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotInfo.parameterSet);
            foreach (var item in parameterInfo.parameters)
            {
                //此处存疑，目前看所有更新的参数都是良率，为什么不写死Yield?
                var parameterId = item.parameterId.Split('-');
                var paraName = parameterId[parameterId.Length - 1].ToString();
                foreach (var item1 in item.samplePrompts)
                {
                    //此处以waferId + 下划线 + 参数名称命名，在解析公共盘是否存在文件文件时会将解析结果放到lot信息缓存里
                    var name = item1.unitId.Replace("#", "-").ToString() + "_" + paraName;
                    var paraValue = lotInfo.waferInfoDic.ContainsKey(name);
                    foreach (var item2 in item1.readingPrompts)
                    {
                        if (paraValue)
                        {
                            string val = lotInfo.waferInfoDic[name].ToString().Replace("%", "");
                            if (string.IsNullOrEmpty(val))
                            {
                                TrackoutLogger.Information("name：" + name + "对应值为空，停止出账");
                                return false;
                            }
                            else
                            {
                                item2.dataValue = val;
                            }
                        }
                        else
                        {
                            TrackoutLogger.Information("name：" + name + "对应值不存在，停止出账");
                            return false;
                        }
                    }
                }
            }
            lotInfo.parameterSet = JsonConvert.SerializeObject(parameterInfo);
            return true;
        }

        public bool updateWaferValueList(LotInfo lotInfo)
        {

            var parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotInfo.parameterSet);
            foreach (var item in parameterInfo.parameters)
            {
                //获取MES需要收值的点位，全部set到value中
                var parameterId = item.parameterId.Split('-');
                var paraName = parameterId[parameterId.Length - 1].ToString();
                foreach (var item1 in item.samplePrompts)
                {
                    var waferId = item1.unitId.Replace("#", "-");
                    Wafer wafer = lotInfo.waferList.FirstOrDefault(o => o.waferId.StartsWith(waferId) || o.waferId.Substring(0, o.waferId.Length - 3) == waferId);
                    if (wafer == null)
                    {
                        TrackoutLogger.Information("waferID：" + waferId + "缓存不存在，停止出账");
                        return false;
                    }
                    var name = item1.unitId.Replace("#", "-").ToString() + "_" + paraName;
                    var paraValue = lotInfo.waferInfoDic.ContainsKey(name);
                    foreach (var item2 in item1.readingPrompts)
                    {
                        string dataVaule = "";
                        if (wafer.valueMap.ContainsKey(paraName) && wafer.valueMap[paraName].Count < 10)
                        {
                            dataVaule = (string)wafer.valueMap[paraName][int.Parse(item2.readingSequence) - 1];
                        }
                        else
                        {
                            TrackoutLogger.Information("waferID：" + waferId + "dataVaule缓存" + dataVaule + "不存在，停止出账");
                            return false;
                        }
                        if (!string.IsNullOrEmpty(dataVaule))
                        {
                            item2.dataValue = dataVaule;
                        }
                        else
                        {
                            TrackoutLogger.Information("收值datavalue失败，停止出账");
                            return false;
                        }
                    }
                }
            }
            lotInfo.parameterSet = JsonConvert.SerializeObject(parameterInfo);
            return true;
        }

        public bool IsSampleProduct(LotInfo lotInfo)
        {

            var parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotInfo.parameterSet);
            foreach (var item in parameterInfo.parameters)
            {
                var parameterId = item.parameterId.Split('-');
                var paraName = parameterId[parameterId.Length - 1].ToString();
                if (paraName != "P50")
                {
                    return false;
                }
            }
            return true;
        }

        public bool updateP50Median(LotInfo lotInfo)
        {

            var parameterInfo = JsonConvert.DeserializeObject<mvOutParameterSet>(lotInfo.parameterSet);
            foreach (var item in parameterInfo.parameters)
            {
                //获取MES需要收值的点位，全部set到value中
                var parameterId = item.parameterId.Split('-');
                var paraName = parameterId[parameterId.Length - 1].ToString();
                if (paraName != "P50")
                {
                    TrackoutLogger.Information($"只能收P50，当前参数名称：{paraName} {parameterId}");
                    return false;
                }
                foreach (var item1 in item.samplePrompts)
                {
                    var waferId = item1.unitId.Replace("#", "-");
                    Wafer wafer = lotInfo.waferList.FirstOrDefault(o => o.waferId.StartsWith(waferId) || o.waferId.Substring(0, o.waferId.Length - 3) == waferId);
                    if (wafer == null || !wafer.p50MedianFlag)
                    {
                        TrackoutLogger.Information("waferID：" + waferId + "P50缓存不存在，停止出账");
                        return false;
                    }
                    foreach (var item2 in item1.readingPrompts)
                    {
                        if (!string.IsNullOrEmpty(wafer.p50Median))
                        {
                            item2.dataValue = wafer.p50Median;
                        }
                        else
                        {
                            TrackoutLogger.Information("收值datavalue失败，停止出账");
                            return false;
                        }
                    }
                }
            }
            lotInfo.parameterSet = JsonConvert.SerializeObject(parameterInfo);
            return true;
        }


        public bool checkPassDie(string mapFile, string waferId, string passNo)
        {
            var WaferInfoList = mapFile.Split("\r\n");
            for (int i = 0; i < WaferInfoList.Length; i++)
            {
                var waferInfo = WaferInfoList[i].ToString().Split(":");
                if (waferInfo.Length == 2 && waferInfo[0] != "RowData")
                {
                    if (!CItems.waferInfoDic.ContainsKey(waferId + "_" + waferInfo[0]))
                        CItems.waferInfoDic.Add(waferId + "_" + waferInfo[0], waferInfo[1]);
                    else
                        CItems.waferInfoDic[waferId + "_" + waferInfo[0]] = waferInfo[1];
                    if (waferInfo[0].ToUpper().Equals("PASSDIE") && waferInfo[1] != passNo)
                    {
                        CimLogger.Information($"waferId:{waferId} is CP MAP count {waferInfo[1]},EQP count {passNo},lot hold!");
                        //var msg = $"waferId:{slidesId} is CP MAP count {waferInfo[1]},EQP count {passDie},lot hold!";
                        var messages = TranslateMsg.GetTranslation("CheckWaferNG", waferId, waferInfo[1], passNo);
                        ClientService.ShowMessage(Dict.Current.TesterID, MessageType.Alarm, messages, MessageOrigin.OCR);
                        return false;
                    }
                }
            }
            CimLogger.Information("true:" + waferId + ":" + passNo + JsonConvert.SerializeObject(CItems.waferInfoDic));
            return true;
        }
        public bool checkPassDieAndSavePara(LotInfo lotInfo)
        {
            List<Wafer> waferList = lotInfo.waferList;
            foreach (Wafer wafer in waferList)
            {
                var waferId = wafer.waferId.Split("-")[0] + "-" + wafer.waferId.Split("-")[1];
                var passNo = wafer.passNo;
                var filePath = CItems.FtpAddress + "\\CP\\CP1\\" + waferId + ".txt";
                var waferParaList = System.IO.File.ReadAllText(filePath).Split("\r\n");
                for (int i = 0; i < waferParaList.Length; i++)
                {

                    var waferPara = waferParaList[i].ToString().Split(":");
                    if (waferPara.Length == 2 && waferPara[0] != "RowData")
                    {
                        if (!lotInfo.waferInfoDic.ContainsKey(waferId + "_" + waferPara[0]))
                            lotInfo.waferInfoDic.Add(waferId + "_" + waferPara[0], waferPara[1]);
                        else
                            lotInfo.waferInfoDic[waferId + "_" + waferPara[0]] = waferPara[1];
                        if (waferPara[0].ToUpper().Equals("PASSDIE") && waferPara[1] != passNo)
                        {
                            TrackoutLogger.Error($"waferId:{waferId} is CP MAP count {waferPara[1]},EQP count {passNo},lot hold!");
                            //var messages = TranslateMsg.GetTranslation("CheckWaferNG", waferId, waferPara[1], passNo);
                            //ClientService.ShowMessage(Dict.Current.TesterID, MessageType.Alarm, messages, MessageOrigin.OCR);
                            //HoldLotByLotInfo(lotInfo, $"EAP中 WaferID:{waferId},对应passNo{passNo}与共享盘Map PassNo:{waferPara[1]}不一致，务必请PE确认");
                            return false;
                        }
                    }
                }
                TrackoutLogger.Information("PassNo比对成功:" + waferId + ":" + passNo);
            }
            return true;
        }
        public static double stringToDouble(String a)
        {
            double b = Double.Parse(a);
            DecimalFormat df = new DecimalFormat("#.0");//此为保留1位小数，若想保留2位小数，则填写#.00 ，以此类推
            String temp = df.Format(b);
            b = Double.Parse(temp);
            return b;
        }
        public bool checkP50AndSavePara(LotInfo lotInfo)
        {
            List<Wafer> waferList = lotInfo.waferList;
            foreach (Wafer wafer in waferList)
            {
                var waferId = wafer.waferId.Split("-")[0] + "-" + wafer.waferId.Split("-")[1];
                wafer.p50Median = Convert.ToDouble(wafer.p50Median).ToString("0.0");
                var filePath = CItems.FtpAddress + "\\CP\\CP1\\" + waferId + ".txt";
                var waferParaList = System.IO.File.ReadAllText(filePath).Split("\n");
                bool p50Flag = false;
                for (int i = 0; i < waferParaList.Length; i++)
                {

                    var waferPara = waferParaList[i].ToString().Split(":");
                    if (waferPara.Length == 2 && waferPara[0].ToUpper() == "P50")
                    {
                        wafer.p50MedianFlag = true;
                        if (double.Parse(waferPara[1]) == double.Parse(wafer.p50Median))
                        {
                            if (!lotInfo.waferInfoDic.ContainsKey(waferId + "_" + waferPara[0]))
                                lotInfo.waferInfoDic.Add(waferId + "_" + waferPara[0], waferPara[1]);
                            else
                                lotInfo.waferInfoDic[waferId + "_" + waferPara[0]] = waferPara[1];

                            TrackoutLogger.Information($"waferId:{waferId}_{waferPara[0]}收值为 {waferPara[1]}!");
                        }
                        else
                        {
                            TrackoutLogger.Information($"waferId:{waferId} P50 中位数与Map不一致{waferPara[1]},EQP {wafer.p50Median}!");
                            return false;
                        }
                    }
                }
            }
            return true;
        }


    }
}
